Slow streaming TCP sockets

elektrobank

Member
Joined
Aug 11, 2008
Messages
19
Programming Experience
10+
I wrote a server application that was using UDP to receive data. The server needs to respond very quickly to the incoming data and produce near-real-time output. Using UDP, this works just fine. However I need to switch to using TCP. But when I do so, there was a noticeable lag with the incoming traffic. I played around with the buffer size, but it didn't make a difference. All the rest of the code is the same, I'm just using TCP instead of UDP. Can anything think of any reason for the slow down?

I have a similar server that I wrote for Unix that uses straight up BSD sockets, and it has no noticeable difference when I switched to TCP, so it appears to have to do with .NET.

I'm using asynchronous TCP sockets.
 
Could it be related to StreamWriter.AutoFlush Property ?
 
I'm not using the TcpListener, I'm using asynchronous sockets, so they should be dumping data as the buffer fills, which they are, but for some reason there is a lag somewhere that I can't figure out. The UDP version works fine, so I know it's not my processing code that's the problem.

The autoflush property is used on the client end right? The client is written in C, and it's not the problem because it doesn't have this problem with a server that was written in C, it only has a problem with the .NET version of the server I wrote. Any other ideas?
 
I guess you mean TcpClient (= Socket+NetworkStream), TcpListener isn't used for communication. You can have a look into Socket/TcpClient.NoDelay Property also. As for async/sync for Socket/TcpClient it is a calling convention that does not affect buffering, when using async methods the Blocking property also have no effect.
 
I've tried setting the NoDelay property of the socket and it didn't make a difference.

This is my code:

Private Function startServer() As Boolean

Try

listener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

listener.NoDelay = True

listener.Bind(New IPEndPoint(IPAddress.Any, localPort))

listener.Listen(10)

listener.BeginAccept(New AsyncCallback(AddressOf connectionRequest), listener)

Return True

Catch ex As Exception

MsgBox(ex.Message)

Return False

End Try

End Function

Private Sub connectionRequest(ByVal ar As IAsyncResult)

Dim listener As Socket = CType(ar.AsyncState, Socket)
Dim handler As Socket = listener.EndAccept(ar)

Dim remoteEndPoint As IPEndPoint

remoteEndPoint = handler.RemoteEndPoint

listener.Listen(10)

listener.BeginAccept(New AsyncCallback(AddressOf connectionRequest), listener)

Dim state As New StateObject
state.workSocket = handler

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf dataArrival), state)

End Sub

Public Sub dataArrival(ByVal ar As IAsyncResult)

Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.workSocket

' Read data from the client socket.
If (handler.Connected()) Then

Dim bytesRead As Integer = handler.EndReceive(ar)

If bytesRead > 0 Then

' Do stuff

End If

End If

End Sub
 
The Socket returned from EndAccept is the Socket you are using to communicate with (typically the "TcpClient"). If any, this is the Socket you have to configure NoDelay for.
 
Back
Top