Multithreaded Networking App

  • Thread starter Thread starter Nathan Neitzke
  • Start date Start date
N

Nathan Neitzke

I just wanted to ask if it is an acceptable practice in a
multithreaded app to pass a socket back to another thread
that has been returned from the Socket.Accept() method?
What happens if they socket on the receiving thread is
closed? Also, do the connections keep on pending until
the socket passed to the other thread is closed? Or can
I continue to Accept more connections?

Thanks,
Nathan Neitzke
 
Hello Nathan,

It would be best to post these questions in the following newsgroup.

Microsoft.public.Win32.Programmer.Networks

All socket programming issues, configuration and other questions are posted in the newsgroup above.

The reason why we recommend posting appropriately is you will get the most qualified pool of respondents, and other
partners who the newsgroups regularly can either share their knowledge or learn from you. Thank you for your
understanding.

Best regards,
yhhuang
VS.NET, Visual C++
Microsoft

This posting is provided "AS IS" with no warranties, and confers no rights.
Got .Net? http://www.gotdotnet.com
--------------------
!Content-Class: urn:content-classes:message
!From: "Nathan Neitzke" <[email protected]>
!Sender: "Nathan Neitzke" <[email protected]>
!Subject: Multithreaded Networking App
!Date: Wed, 9 Jul 2003 18:55:18 -0700
!Lines: 10
!Message-ID: <[email protected]>
!MIME-Version: 1.0
!Content-Type: text/plain;
! charset="iso-8859-1"
!Content-Transfer-Encoding: 7bit
!X-Newsreader: Microsoft CDO for Windows 2000
!Thread-Index: AcNGhlB/p5NzEJ/8RzW4zE0R3JeW9w==
!X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
!Newsgroups: microsoft.public.dotnet.framework
!Path: cpmsftngxa06.phx.gbl
!Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:48568
!NNTP-Posting-Host: TK2MSFTNGXA12 10.40.1.164
!X-Tomcat-NG: microsoft.public.dotnet.framework
!
!I just wanted to ask if it is an acceptable practice in a
!multithreaded app to pass a socket back to another thread
!that has been returned from the Socket.Accept() method?
!What happens if they socket on the receiving thread is
!closed? Also, do the connections keep on pending until
!the socket passed to the other thread is closed? Or can
!I continue to Accept more connections?
!
!Thanks,
!Nathan Neitzke
!
 
Hi Nathan,

1. It's acceptable to pass a socket back to another thread that has been
returned from the "Socket.Accept()" method. But I recommend you use the
Asynchronous Socket to do this.

Asynchronous sockets use threads from the system thread pool to process
incoming connections. One thread is responsible for accepting connections,
another thread is used to handle each incoming connection, and another
thread is responsible for receiving data from the connection. These could
be the same thread, depending on which thread is assigned by the thread
pool. In the following example, the System.Threading.ManualResetEvent class
suspends execution of the main thread and signals when execution can
continue.

public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];

// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );

// Bind the socket to the local endpoint and listen for incoming
connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);

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(AcceptCallback),
listener );

// Wait until a connection is made before continuing.
allDone.WaitOne();
}

}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

Console.WriteLine("\nPress ENTER to continue...");
Console.Read();

}


public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();

// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);

// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}

You can check MSDN for more information:

Asynchronous Server Socket Example
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconnon-blockingserversocketexample.asp

Asynchronous Client Socket Example
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconnon-blockingclientsocketexample.asp

2. If you want to receive data on the same socket continuously,you should
add this line after you have received data from the client:

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new
AsyncCallback(ReadCallback), state);

Then if data comes,ReadCallback method will be called again.

public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;

// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead=0;

// Read data from the client socket.
try
{
if(handler.Connected)bytesRead = handler.EndReceive(ar);
}
catch// If the client disconnected due to network issues
{
CloseSocket(handler);
return;
}

if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));

// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content );
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new
AsyncCallback(ReadCallback), state);
}
else if (bytesRead == 0)// Client calls Shutdown(SocketShutdown.Both) to
shutdown the socket.
{
CloseSocket(handler);
}
}

public static void CloseSocket(Socket handler)
{
if(handler.Connected)
{
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
Console.WriteLine("the client closed") ;
}

If the socket on the receiving thread is closed(because the client calls
Shutdown(SocketShutdown.Both)), the ReadCallback method will be called, but
the bytesRead is 0.Then you can close the socket on the server side.

If the client disconnected due to network issues, the ReadCallback method
will also be called. But the EndReceive will throw an exception. Then you
can catch the exception and close the socket.

3. The connections keep on pending until the socket is disconnected.

If you want to Accept more connections,you can put BeginAccept method in a
while(true){ ... } loop.You can see the StartListening method for more
information on how to implement it.

Best Regards,
Lewis Wang

This posting is provided "AS IS" with no warranties, and confers no rights.




--------------------
| Content-Class: urn:content-classes:message
| From: "Nathan Neitzke" <[email protected]>
| Sender: "Nathan Neitzke" <[email protected]>
| Subject: Multithreaded Networking App
| Date: Wed, 9 Jul 2003 18:55:18 -0700
| Lines: 10
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcNGhlB/p5NzEJ/8RzW4zE0R3JeW9w==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.public.dotnet.framework
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:48568
| NNTP-Posting-Host: TK2MSFTNGXA12 10.40.1.164
| X-Tomcat-NG: microsoft.public.dotnet.framework
|
| I just wanted to ask if it is an acceptable practice in a
| multithreaded app to pass a socket back to another thread
| that has been returned from the Socket.Accept() method?
| What happens if they socket on the receiving thread is
| closed? Also, do the connections keep on pending until
| the socket passed to the other thread is closed? Or can
| I continue to Accept more connections?
|
| Thanks,
| Nathan Neitzke
|
 
Back
Top