-1

I'm trying to write an asynch socket application which transfering complex objects over across sides..

I used the example here...

Everything is fine till i try send multi package data. When the transferred data requires multiple package transfer server application is suspending and server is going out of control without any errors...

After many hours later i find a solution; if i close client sender socket after each EndSend callback, the problem is solving. But i couldn't understand why this is necessary? Or are there any other solution for the situation?

My (2) projects is same with example above only i changed EndSend callback method like following:

    public void EndSendCallback(IAsyncResult result)
    {
        Status status = (Status)result.AsyncState;
        int size = status.Socket.EndSend(result);
        status.Socket.Close(); // <--------------- This line solved the situation
        Console.Out.WriteLine("Send data: " + size + " bytes.");
        Console.ReadLine();
        allDone.Set(); 
    }

Thanks..

DortGen
  • 402
  • 2
  • 8
  • 22

1 Answers1

0

This is due to the example code given not handling multiple packages (and being broken).

A few observations:

  • The server can only handle 1 client at a time.
  • The server simply checks whether the data coming in is in a single read smaller than the data requested and if so, assumes that's the last part.
  • The server then ignores the client socket while leaving the connection open. This puts the responsibility of closing the connection on the client side which can be confusing and which will waste resources on the server.

Now the first observation is an implementation detail and not really relevant in your case. The second observation is relevant for you since it will likely result in unexplained bugs- probably not in development- but when this code is actually running somewhere in a real scenario. Sockets are not streamlined. When the client sents over 1000 bytes. This might require 1 call to read on the server or 10. A call to read simply returns as soon as there is 'some' data available. What you need to do is implement some sort of protocol that communicates either how much data is being sent over- or when all the data has been sent over. I really recommend just to stick with the HTTP protocol since this is a well tested and well supported protocol that suits most scenario's.

The third observation might also cause bugs where the server is running out of resources since it leaves all connections open.

Polity
  • 14,734
  • 2
  • 40
  • 40
  • 1
    Hey Polity, thanks for the heads up! I hadn't encountered these bugs myself, but after looking at the (old) code again I think you're right. If exact multiples of the package size are sent it might get stuck reading while nothing is being sent anymore. I've added a disclaimer to the blog post and when I have time I will write a new version that works properly. (I'll also have to check a few projects that I used it in :P). – Roy T. Sep 09 '12 at 08:06
  • Ok, I've created a new version of that tutorial (much cleaner code, better example, less bugs (hopefully). You can find it here http://roy-t.nl/index.php/2012/09/09/c-asynchronous-sockets-revisited/ – Roy T. Sep 09 '12 at 12:40
  • Thanks for your help, but your new article is same example of a combination of MSDN articles http://msdn.microsoft.com/en-us/library/w89fhyex. I'm looking for an example of transfering custom objects via TCP socket, I dont want to use HTTP or WCF services or any other thing.. – DortGen Sep 09 '12 at 17:55