473,237 Members | 1,415 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,237 software developers and data experts.

Asynchronous Socket Server Question

I am trying to create a socket server which will listen for connections from
multiple clients and call subroutines in a Fortran DLL and pass the results
back to the client. The asynchronous socket client and asynchronous socket
server example code provided in the .NET framework developers guide is a
great start but I have not dealt with sockets before and I am struggling with
something.

From what I can tell the sample server code provided will only listen to
one incomming connection at a time and the backlog can be set to allow more
connections to que up ready for processing when the current connection is
completed.
While True
' Set the event to nonsignaled state.
allDone.Reset()

' Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback),
listener)

' Wait until a connection is made and processed before continuing.
allDone.WaitOne()
End While
While the documentation indicates that connections to an asychronous socket
may be completed in a different order than that in which they were recieved,
it appears to me that the listener will only accept a connection is when the
allDone.Set event occurs and the loop can start a new iteration.

What I would like to happen is:

Accept input request (0)
on the thread created to receive request(0) perform the call to my Fortran
DLL and return the output to the client.

While request(0) is being processed on its own thread the main thread should
be able to accept input request(1)

on the thread created to receive request(1) perform the call to my Fortran
DLL and return the output to the client.

While request(0) and request(1) are being processed on their own threads the
main thread should be able to accept input request(2)

etc.

Am I off base?
How can I get more than one thread reading input from the socket at the same
time?

Thanks,
Erik
Oct 26 '06 #1
4 3575

Engineerik wrote:
I am trying to create a socket server which will listen for connections from
multiple clients and call subroutines in a Fortran DLL and pass the results
back to the client. The asynchronous socket client and asynchronous socket
server example code provided in the .NET framework developers guide is a
great start but I have not dealt with sockets before and I am struggling with
something.

From what I can tell the sample server code provided will only listen to
one incomming connection at a time and the backlog can be set to allow more
connections to que up ready for processing when the current connection is
completed.
While True
' Set the event to nonsignaled state.
allDone.Reset()

' Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback),
listener)

' Wait until a connection is made and processed before continuing.
allDone.WaitOne()
End While
While the documentation indicates that connections to an asychronous socket
may be completed in a different order than that in which they were recieved,
it appears to me that the listener will only accept a connection is when the
allDone.Set event occurs and the loop can start a new iteration.

What I would like to happen is:

Accept input request (0)
on the thread created to receive request(0) perform the call to my Fortran
DLL and return the output to the client.

While request(0) is being processed on its own thread the main thread should
be able to accept input request(1)

on the thread created to receive request(1) perform the call to my Fortran
DLL and return the output to the client.

While request(0) and request(1) are being processed on their own threads the
main thread should be able to accept input request(2)

etc.

Am I off base?
Yes :) I don't mean that in a mean way.
How can I get more than one thread reading input from the socket at the same
time?
Just follow the async example. It does exactly that. See, the way a
server socket works is that it is bound to a particular port. When a
client comes in, the accept socket call returns with a handle to a new
socket - in other words, communication does not take place over the
server socket. The listener is simply a means for allowing clients to
connect to a known endpoint, once connected they will not be
communicating on the same port as the server.

In psuedo code, syncrounous sockets look something like:

while (true)
socket client = server.accept () ' blocks until there are pending
connections
spawnthread (client) ' pas the new socket to a thread for processing
wend

This is what the async calls are doing... Only it doesn't wait for
accept to return, it uses the event to signal when it can call accept
again (there can only be one accept at a time). Now you are right that
there is a queue for new connections - a server can only accept one
connection at a time, and that is what the backlog does is set the max
size of that queue before the server socket refuses to allow the
connection. I hope I'm making this clear...

--
Tom Shelton

Oct 27 '06 #2
Thanks for the explanation, however...
Two more related questions,
In the read callback,
Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)
Dim content As String = String.Empty

' Retrieve the state object and the handler socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.workSocket

' Read data from the client socket.
Dim bytesRead As Integer = handler.EndReceive(ar)

If bytesRead 0 Then
' There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buf fer, 0,
bytesRead))

' Check for end-of-file tag. If it is not there, read
' more data.
content = state.sb.ToString()
If content.IndexOf("<EOF>") -1 Then
' All the data has been read from the
' client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. " + vbLf + "
Data : {1}", content.Length, content)
' Echo the data back to the client.
Send(handler, content)
Else
' Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,
StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End If
End If
End Sub 'ReadCallback

Question 1
Is there a good way to determine when the full string has been read other
than searching for some end-of-input-flag like the "<EOF>"?

Question 2 (This really is the crux of my question)
How do I respond to the client if the user fails to include "<EOF>" in the
string passed to the server? The sample code has no timeout so the client
just waits forever and never gets any reply from the server.

I made 2 different client exes
Client1 does not pass "<EOF>" at the end of the string.
Client2 includes "<EOF>"

If I run client1 first then run client2 client1 waits forever because
Send(handler,content) never gets called. However, client 2 also never
returns. That is why I asked my first question. Clearly, client2 input is
not getting processed because the main thread is blocked waiting for the
client1 thread to call alldone.set which will never happen.

This leads me to think that if client1 sent a valid but time consuming
request then the server would block until the client1 request was completed
before it would do anything with the client2 request which may have been
simple and should have returned to client2 long before the request from
client1 finished being processed.
"Tom Shelton" wrote:
>
Engineerik wrote:
I am trying to create a socket server which will listen for connections from
multiple clients and call subroutines in a Fortran DLL and pass the results
back to the client. The asynchronous socket client and asynchronous socket
server example code provided in the .NET framework developers guide is a
great start but I have not dealt with sockets before and I am struggling with
something.

From what I can tell the sample server code provided will only listen to
one incomming connection at a time and the backlog can be set to allow more
connections to que up ready for processing when the current connection is
completed.
While True
' Set the event to nonsignaled state.
allDone.Reset()

' Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback),
listener)

' Wait until a connection is made and processed before continuing.
allDone.WaitOne()
End While
While the documentation indicates that connections to an asychronous socket
may be completed in a different order than that in which they were recieved,
it appears to me that the listener will only accept a connection is when the
allDone.Set event occurs and the loop can start a new iteration.

What I would like to happen is:

Accept input request (0)
on the thread created to receive request(0) perform the call to my Fortran
DLL and return the output to the client.

While request(0) is being processed on its own thread the main thread should
be able to accept input request(1)

on the thread created to receive request(1) perform the call to my Fortran
DLL and return the output to the client.

While request(0) and request(1) are being processed on their own threads the
main thread should be able to accept input request(2)

etc.

Am I off base?

Yes :) I don't mean that in a mean way.
How can I get more than one thread reading input from the socket at the same
time?

Just follow the async example. It does exactly that. See, the way a
server socket works is that it is bound to a particular port. When a
client comes in, the accept socket call returns with a handle to a new
socket - in other words, communication does not take place over the
server socket. The listener is simply a means for allowing clients to
connect to a known endpoint, once connected they will not be
communicating on the same port as the server.

In psuedo code, syncrounous sockets look something like:

while (true)
socket client = server.accept () ' blocks until there are pending
connections
spawnthread (client) ' pas the new socket to a thread for processing
wend

This is what the async calls are doing... Only it doesn't wait for
accept to return, it uses the event to signal when it can call accept
again (there can only be one accept at a time). Now you are right that
there is a queue for new connections - a server can only accept one
connection at a time, and that is what the backlog does is set the max
size of that queue before the server socket refuses to allow the
connection. I hope I'm making this clear...

--
Tom Shelton

Oct 27 '06 #3


"Engineerik" wrote:
>
I made 2 different client exes
Client1 does not pass "<EOF>" at the end of the string.
Client2 includes "<EOF>"

If I run client1 first then run client2 client1 waits forever because
Send(handler,content) never gets called. However, client 2 also never
returns. That is why I asked my first question. Clearly, client2 input is
not getting processed because the main thread is blocked waiting for the
client1 thread to call alldone.set which will never happen.

This leads me to think that if client1 sent a valid but time consuming
request then the server would block until the client1 request was completed
before it would do anything with the client2 request which may have been
simple and should have returned to client2 long before the request from
client1 finished being processed.
OK, Sorry to be so dense on the blocking issue.
I realize from your comments that I needed to move the alldone.reset to the
AcceptCallback sub instead of leaving it in the ReadCallback. The sample
code should probably have it there also in order to represent a truely
asynchronous server.

I am still wondering though how to deal with input which omits the "<EOF>".
I would like to be able to send some sort of error message back to the client
in that case.

Thanks for the assistance.
Erik
Oct 27 '06 #4


"Engineerik" wrote:
>
Question 1
Is there a good way to determine when the full string has been read other
than searching for some end-of-input-flag like the "<EOF>"?
AHA!
I think I just found the answer to that...
if handler.available = 0 then all bytes passes from the client have been
accepted by the server.

Erik

Oct 27 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Corne Oosthuizen | last post by:
I'm writing a Telnet Server application using Asynchronous sockets. I spawn a listener thread to handel incomming connections and create a separate client socket for each new connection. I...
3
by: Matthew King | last post by:
Hi all I've written a asynchronous socket client class, but i've found that in order to consume it I have to use events, and cannot simply for example SocketClient client = new...
7
by: Colin | last post by:
I'm writing a little console socket server but I'm having some difficulty. Can I ask your advice - where is the best place to get some help on that topic? It would be nice if some people who knew...
4
by: Macca | last post by:
I am writing an application that uses asynchronous sockets to get data over ethernet from embedded devices, up to 30 concurrent devices.(These devices are written in C). My application...
2
by: Macca | last post by:
My app has an asynchronous socket server. It will have 20 clients connected to the server. Each client sends data every 500 millisecondsThe Connections once established will not be closed unless...
0
by: Macca | last post by:
Hi, I am writing an asychronous socket server to handle 20+ simulataneous connections. I have used the example in MSDN as a base. The code is shown at end of question. Each connection has a...
6
by: Pat B | last post by:
Hi, I'm writing my own implementation of the Gnutella P2P protocol using C#. I have implemented it using BeginReceive and EndReceive calls so as not to block when waiting for data from the...
2
by: Nicolas Le Gland | last post by:
Hello everyone here. This is my first post in this newsgroup, I hope I won't be to much off-topic. Feel free to redirect me to any better group. I am getting strange timing issues when...
1
by: keksy | last post by:
Hi every1, I am writing a small client/server application and in it I want to send an image asynchronous from the client to the server through a TCP socket. I found an example code on the MSDN...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.