locked
Multiple TCP connections RRS feed

  • Question

  • Hi,

    I am looking for a code to handle multiple async connections on a TCP port, I have seen a lot of samples on the net, some people uses callbacks some other threads, but what is the most efficient way to do it?

    One of the examples I found from Microsoft:

    Imports System.Net
    Imports System.Net.Sockets
    Imports System.Threading
    Imports System.Text
    
    ' State object for receiving data from remote device.  
    Public Class StateObject
    	' Client socket.  
    	Public workSocket As Socket = Nothing
    	' Size of receive buffer.  
    	Public Const BufferSize As Integer = 256
    	' Receive buffer.  
    	Public buffer As Byte() = New Byte(BufferSize - 1) {}
    	' Received data string.  
    	Public sb As New StringBuilder()
    End Class
    
    Public Class AsynchronousClient
    	' The port number for the remote device.  
    	Private Const port As Integer = 11000
    
    	' ManualResetEvent instances signal completion.  
    	Private Shared connectDone As New ManualResetEvent(False)
    	Private Shared sendDone As New ManualResetEvent(False)
    	Private Shared receiveDone As New ManualResetEvent(False)
    
    	' The response from the remote device.  
    	Private Shared response As [String] = [String].Empty
    
    	Private Shared Sub StartClient()
    		' Connect to a remote device.  
    		Try
    			' Establish the remote endpoint for the socket.  
    			' The name of the   
    			' remote device is "host.contoso.com".  
    			Dim ipHostInfo As IPHostEntry = Dns.Resolve("host.contoso.com")
    			Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
    			Dim remoteEP As New IPEndPoint(ipAddress, port)
    
    			' Create a TCP/IP socket.  
    			Dim client As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    
    			' Connect to the remote endpoint.  
    			client.BeginConnect(remoteEP, New AsyncCallback(AddressOf ConnectCallback), client)
    			connectDone.WaitOne()
    
    			' Send test data to the remote device.  
    			Send(client, "This is a test<EOF>")
    			sendDone.WaitOne()
    
    			' Receive the response from the remote device.  
    			Receive(client)
    			receiveDone.WaitOne()
    
    			' Write the response to the console.  
    			Console.WriteLine("Response received : {0}", response)
    
    			' Release the socket.  
    			client.Shutdown(SocketShutdown.Both)
    
    			client.Close()
    		Catch e As Exception
    			Console.WriteLine(e.ToString())
    		End Try
    	End Sub
    
    	Private Shared Sub ConnectCallback(ar As IAsyncResult)
    		Try
    			' Retrieve the socket from the state object.  
    			Dim client As Socket = DirectCast(ar.AsyncState, Socket)
    
    			' Complete the connection.  
    			client.EndConnect(ar)
    
    			Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString())
    
    			' Signal that the connection has been made.  
    			connectDone.[Set]()
    		Catch e As Exception
    			Console.WriteLine(e.ToString())
    		End Try
    	End Sub
    
    	Private Shared Sub Receive(client As Socket)
    		Try
    			' Create the state object.  
    			Dim state As New StateObject()
    			state.workSocket = client
    
    			' Begin receiving the data from the remote device.  
    			client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
    		Catch e As Exception
    			Console.WriteLine(e.ToString())
    		End Try
    	End Sub
    
    	Private Shared Sub ReceiveCallback(ar As IAsyncResult)
    		Try
    			' Retrieve the state object and the client socket   
    			' from the asynchronous state object.  
    			Dim state As StateObject = DirectCast(ar.AsyncState, StateObject)
    			Dim client As Socket = state.workSocket
    
    			' Read data from the remote device.  
    			Dim bytesRead As Integer = client.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.buffer, 0, bytesRead))
    
    				' Get the rest of the data.  
    				client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
    			Else
    				' All the data has arrived; put it in response.  
    				If state.sb.Length > 1 Then
    					response = state.sb.ToString()
    				End If
    				' Signal that all bytes have been received.  
    				receiveDone.[Set]()
    			End If
    		Catch e As Exception
    			Console.WriteLine(e.ToString())
    		End Try
    	End Sub
    
    	Private Shared Sub Send(client As Socket, data As [String])
    		' Convert the string data to byte data using ASCII encoding.  
    		Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
    
    		' Begin sending the data to the remote device.  
    		client.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), client)
    	End Sub
    
    	Private Shared Sub SendCallback(ar As IAsyncResult)
    		Try
    			' Retrieve the socket from the state object.  
    			Dim client As Socket = DirectCast(ar.AsyncState, Socket)
    
    			' Complete sending the data to the remote device.  
    			Dim bytesSent As Integer = client.EndSend(ar)
    			Console.WriteLine("Sent {0} bytes to server.", bytesSent)
    
    			' Signal that all bytes have been sent.  
    			sendDone.[Set]()
    		Catch e As Exception
    			Console.WriteLine(e.ToString())
    		End Try
    	End Sub
    
    	Public Shared Function Main(args As [String]()) As Integer
    		StartClient()
    		Return 0
    	End Function
    End Class


    G.Waters

    Monday, November 6, 2017 1:07 AM

Answers

  • Maybe review this Reed Kimble article and code Simple Multi-User TCP/IP Client & Server using TAP as it probably has the most effective and efficient method for doing so but will require a learning curve to get in step with the abilities and uses of TAP I suppose.

    La vida loca

    • Marked as answer by George Waters Wednesday, November 8, 2017 7:18 PM
    Wednesday, November 8, 2017 6:34 PM
  • George,

    The computer (PC and Server) hardware itself which you use is probably fast enough at any way. It is most of the time waiting for data. 

    Therefore shortening this wait time outside your program is probably 10000 times more important than winning processor time. 

    Therefore focus on that, winning 3 microseconds in a process of 10 seconds is mostly a waste of time. 

    Of course you need to do this asynchronously in any way. But a more important point to take attention to is the quantity of lines which you are concurrently using. Some take endless lines where most of the time is wasted by deciding which one to take. 

    Don't think these people on this picture can quicker enter all at the same time if the try to let them pass the ports all togheter 


    Success
    Cor



    • Edited by Cor Ligthert Wednesday, November 8, 2017 6:59 PM
    • Marked as answer by George Waters Wednesday, November 8, 2017 7:18 PM
    Wednesday, November 8, 2017 6:58 PM

All replies

  • Hi George,

    You can  try TcpListener Class for connections from TCP network clients.

    https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener(v=vs.110).aspx

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 7, 2017 6:38 AM
  • Maybe review this Reed Kimble article and code Simple Multi-User TCP/IP Client & Server using TAP as it probably has the most effective and efficient method for doing so but will require a learning curve to get in step with the abilities and uses of TAP I suppose.

    La vida loca

    • Marked as answer by George Waters Wednesday, November 8, 2017 7:18 PM
    Wednesday, November 8, 2017 6:34 PM
  • George,

    The computer (PC and Server) hardware itself which you use is probably fast enough at any way. It is most of the time waiting for data. 

    Therefore shortening this wait time outside your program is probably 10000 times more important than winning processor time. 

    Therefore focus on that, winning 3 microseconds in a process of 10 seconds is mostly a waste of time. 

    Of course you need to do this asynchronously in any way. But a more important point to take attention to is the quantity of lines which you are concurrently using. Some take endless lines where most of the time is wasted by deciding which one to take. 

    Don't think these people on this picture can quicker enter all at the same time if the try to let them pass the ports all togheter 


    Success
    Cor



    • Edited by Cor Ligthert Wednesday, November 8, 2017 6:59 PM
    • Marked as answer by George Waters Wednesday, November 8, 2017 7:18 PM
    Wednesday, November 8, 2017 6:58 PM
  • Thanks all for your time, it really helped me.

    :)


    G.Waters

    Wednesday, November 8, 2017 7:19 PM