Socket streaming difficulties

Hello

The scenario is as following:

There are two computers talking to each other through socket over a 1Gbps network[low network traffic], the requirement is that the server sends a data packet of barely 500bytes[average--- the packet size is variable-- excluding tcp header and acks.], every 10ms. The data is received reliably [i have checked it].  The data which is recieved is then displayed on the dialogue in form of vector graphics using GDI+. I am using asynchronous sockets. There is a function WaitForData.
           if(cb == null)
                cb = new AsyncCallback(ProcessRecieve);
            sock.BeginReceive(buffer,0,(int)size,SocketFlags.None,cb,null);
The ProcessRecieve Delegate is called by operating system (Windows XP SP2) when the data arrives.
{
     sock.EndReceive(ar);
    .
    .
    .
    Code that reads the buffer, restructures it and invalidates the Form to display the vector        graphics.
    .
    .
    .
    WaitForData();
}


I should also mention that the Form which is invalidated is the child form [which is responsible for displaying vector graphics in OnPaint function], not the parent form [which contains the sockets.]

Note: The application which i described is client application, i haven't mentioned the server application because it is working fine, and delivering the packets well.

Now the problems which arise are the following.

1.  When both applications are running on the same computer, i.e. the ipaddress is "localhost", the application works very well, and displayes the vector graphics very well. and takes cputime of 25% on average.

2. But when the server is running on different machine, Most of the data frames (more that 75%) are skipped. But strangely enough the cpu time doesnot exceed 12%, Because some of the things that must be displayed aren't displayed at all [75% of frames aren't even displayed].

Things i did: 

1. Optimised graphics display by decreasing computations.
2. Incread size of the socket buffer.
3. Naggle algorithm [for tcp packets] is also not the cause of the problem.

My Query:

1. Why are the frames getting skipped when the server is not on the same pc as the client [i am sure that network traffic is not a problem, i checked it].

Thanks in advance to those who help.

Sayed Zeeshan.







Answer this question

Socket streaming difficulties

  • Robert Bell

    Hello

    The problem has been solved.

    I tried using directx instead of GDI+ and it worked, now i am getting all the frames intact.
    Apparantely it appears that when i used GDI+, the processor was busy drawing graphics, and the ProcessRecieve was not called as frequently as it should be and i was missing the frames. But with DirectX the load of graphics was transferred to the adapter and it had enough time to watch the socket. But still i may be incorrect. If someone has any idea please share with me.

    Sayed Zeeshan


  • Adam007x

    Hi,
    To help you find whats going wrong..

    First check if the data frames sent by the server are actually recieved by the client (A TCP/IP connection rarely loses data on a good network).
    In your client application, ignore the code where you draw the graphics, and add some code to make sure that the frames are recived properly.

    On the other hand,

    It is also bad practice to to write write code that draws the graphics in the Recieve delegate.
    What you should do here is just save the data frames in a Queue. Do nothing else. Just save the data that comes from the server.
     Write another class which uses a thread to pick the data frames from the queue and draw the graphics. You should seperate the functionality of recieving data and the actual drawing.

    This ensures that you will not miss any data frames while your code is busy drawing.

    So your client program will be like this..

    DataReciever  class -> All this does is recieves the data frames from the server and place it in the queue. In here make sure you recieve a complete data frame before placing the data frame in the queue. This could be your problem. When both are on the same computer, on each call of ProcessRecieve the client recieves a complete data frame. But when the server is on another computer, due to network conditions you may not receive a complete frame on each ProcessRecieve. Instead you will have to assemble the frame over a one or more ProcessRecive calls, as the data comes in little by little.

    Renderer class -> Has a thread  which reads a data frame from the queue and contains the drawing code.

    Form -> nothing much here.

    Let me know if these suggestions help...

  • Alkazam

    Hello Hibri.

    Thanks for your reply. Smile

    First check if the data frames sent by the server are actually recieved by the client (A TCP/IP connection rarely loses data on a good network). In your client application, ignore the code where you draw the graphics, and add some code to make sure that the frames are recived properly.


    I have done that before, and as i stated before the frames are being received correctly and completely on the client side.

    My classes are doing the same as you suggested, i.e. i am not drawing in ProcessRecieve delegate, rather i only extract the frames brom the buffer and put it in a queue, which is then used by another class which does the drawing. i.e. the recieving and drawing portions are seperate.
    I only call Invalidate function of the child form, in which i am doing the drawing, in the ProcessRecieve delegate. The reason for this is to tell the graphics display to update. And i ensure that the frames are being extracted before i call Invalidate function.

    Looking forward to your next reply.

    Sayed Zeeshan





  • Ajoy

    I urgently need an answer.

    I have checked and it appears to me that the ProcessRecieve delegate is not being called as frequently as it should be maybe tdue to the graphics load, but still its a thought which may or may not be correct.

    Sayed Zeeshan


  • Socket streaming difficulties