• 0

Help with TCP Socket Server Client


Question

Hi,

 

I am trying to write this TCP Socket Client Server app for testing purposes. It works for the most part but some things are not working and I need some help. Please see the project attached created in VS2013 targeting .NET Framework 4.5 using C#.

 

ServerClient.zip

 

I took the socket code from here https://code.msdn.microsoft.com/High-Performance-NET-69c2df2f

 

The issues I am having are,

 

* When I stop listening on server, I am still receiving data. I would expect that the client should find that it is not connected anymore and throw an error and disconnect.

* I need to send server time back to the client upon receiving data (once the receive is complete). I am doing that but it is not working.

* I have set the buffer size to 64 bytes but if I send more data then it doesn't like that. I thought it was possible to grab data to fill that buffer and then continue receiving more until it finishes.

* One last thing might I ask is some suggestions with error handling since the socket code from MSDN says the "LastError" is not the correct way of doing this.

 

So I am way over my head with TCP stuff because I don't do network programming often and need some help to sort of these issues.

 

Cheers :)

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 0

* When I stop listening on server, I am still receiving data. I would expect that the client should find that it is not connected anymore and throw an error and disconnect.

From a cursory glance, it doesn't appear to close accepted sockets in Stop().

public void Stop()
{
ConnectionSocket.Close();
_limitClientConnectionMutex.ReleaseMutex();
}
I don't know C# or .Net sockets very well, but isn't ConnectionSocket merely the listening socket? Calling this function won't actually close/inform the client that you disconnected. In C, I'd usually iterate through the client connections and gracefully shut them down:

for ( iter = list_first ( clients ); NULL != iter; iter = list_next ( clients, iter ) ) {
Socket *s = list_get_ptr ( iter );
shutdown ( s->fd, SHUT_RDWR );
close ( s->fd );
}
list_free ( clients );

* I need to send server time back to the client upon receiving data (once the receive is complete). I am doing that but it is not working.

I'd suggest you debug ProcessData() in the SocketUserToken class. You appear to be setting the non-blocking write buffer for the socket there:

var sendBuffer = Encoding.UTF8.GetBytes(received + " Time : " + DateTime.UtcNow.ToString("O")); // "O" = ISO-8601
args.SetBuffer(sendBuffer, 0, sendBuffer.Length);
You need to confirm this gets executed and does what it's supposed to do before you close the socket. I'm assuming the underlying class automatically sends the buffer once there's data there. If not, you may have to call some kind of send() function.

 

* I have set the buffer size to 64 bytes but if I send more data then it doesn't like that. I thought it was possible to grab data to fill that buffer and then continue receiving more until it finishes.

I think the problem is that you're limiting your packet/message buffer '_stringBuilder' in SocketUserTokenClass to DefaultBufferSize (64 bytes) as well. Specifically in SocketServerClass's ProcessAcept():

readSocket.UserToken = new SocketUserTokenClass(AddToLoggerMethod, acceptSocket, DefaultBufferSize);
Which translates to this executing:

if ((_totalByteCount + bytecount) > _stringBuilder.Capacity)
{
LastError = "Receive Buffer cannot hold the entire message for this connection.";
return false;
}
'_stringBuilder' is set to 64 by your DefaultBufferSize, so if you send any more than that it will error out. To be honest, I think SocketUserTokenClass is just a placeholder for your own custom receive/parsing packet functions. It's very rudimentary. However, provided you change the packet/message buffer size passed into the SocketUserTokenClass constructor, you should be fine. You need to understand that there are actually two buffers involved here. 1) The socket read buffer, and 2) The packet/message buffer. That's how most reliable network code works. You construct the packet/message once you've received the whole thing. That's usually done via encoding such as prefixing the packet size.

 

* One last thing might I ask is some suggestions with error handling since the socket code from MSDN says the "LastError" is not the correct way of doing this.

Sounds a lot like 'errno' from ISO C. There are only really two ways to handle errors:

1) Check return value from a function. Sometimes this is used in conjunction with 'errno' to determine the real error. For instance, the socket() function returns -1 if an error occurred. To obtain the actual error, you can access errno/call strerror().

2) Employ try/catch exception handling. Though in the case of sockets, it might not be efficient. After all, network errors are so common. I suppose it depends on how often you expect them to occur and whether you're willing to accept the performance penalty.

 

So I am way over my head with TCP stuff because I don't do network programming often and need some help to sort of these issues.

Networking is simple once you get the hang of it. You'll be writing your own packet protocols in no time ;)
Link to comment
Share on other sites

This topic is now closed to further replies.