Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a program with server and client both on different machines. What the program do is send continuous images to server from client. Here client send the datasize first and then the data and similarly server receives the data size in byte[4] and reads the data. Everything is working great but after sometime the datasize byte[] returns some invalid value i.e. -17845811547 or 155488798 and so on. I tried reading the sent and received byte[] and it came to my notice that client is sending the data very well and server is receiving but the server is reading the data sometimes correctly and sometimes it's filling the datasize byte[] with invalid values. Below is the code and invalid result.

What I have tried:

Code:
Server -

private static byte[] receiveFullByte(Socket s)
        {
            int total = 0;
            int recv;
            byte[] datasize = new byte[4];

            recv = s.Receive(datasize, 0, 4, 0);
            int size = BitConverter.ToInt32(datasize, 0);
            int dataleft = size;    
            try
            {
                byte[] data = new byte[size];
                while (total < size)
                {
                    if (size > 800000)
                    {
                        return null;
                    }
                    recv = s.Receive(data, total, dataleft, 0);
                    if (recv == 0)
                    {
                        break;
                    }
                    total += recv;
                    dataleft -= recv;
                }
                
                return data;
            }
            catch (Exception ex)
            {
                return null;
            }
        }


Client -
private static void sendDataConti()
        {
            if (clientSocket.Connected)
            {
                string request = "Image|" + localipaddress.ipAddressFind() + "||||";
                byte[] clientBufferByte = Encoding.ASCII.GetBytes(request);
                while (true)
                {
                    //New Code in use below
                    try
                    {
                        using (Bitmap bmp = PrintScreen())
                        {
                            MemoryStream ms = new MemoryStream();
                            bmp.Save(ms, ImageFormat.Jpeg);
                            byte[] buffer = ms.ToArray();
                            byte[] finalArray = new byte[buffer.Length + clientBufferByte.Length];

                            Array.Copy(clientBufferByte, 0, finalArray, 0, clientBufferByte.Length);
                            Array.Copy(buffer, 0, finalArray, clientBufferByte.Length, buffer.Length);

                            SendFullData(finalArray);
                            ms.Dispose();
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                }
            }
        }


private static int SendFullData(byte[] data)
        {
            int total = 0;
            int size = data.Length;
            int dataleft = size;
            int sent;

            try
            {
                //send the size of the data
                byte[] datasize = new byte[4];
                datasize = BitConverter.GetBytes(size);
                sent = clientSocket.Send(datasize);
                clientSocket.Send(datasize);
                Console.WriteLine("Size sent " + size);
                Thread.Sleep(500);
                //send the image data
                while (total < size)
                {
                    sent = clientSocket.Send(data, total, dataleft, SocketFlags.None);
                    Console.WriteLine("Data sent " + sent);
                    total += sent;
                    dataleft -= sent;
                }

                string data2string = Encoding.ASCII.GetString(data);
                string request = data2string.Split('|')[0];

                Thread.Sleep(500);
            }
            catch { }

            return total;
        }


Result:
Client sent data:

//First data sent
Size sent 126128
Byte 1: 176
Byte 2: 236
Byte 3: 1
Byte 4: 0
Data sent 126128
//Second data sent
Size sent 124521
Byte 1: 105
Byte 2: 230
Byte 3: 1
Byte 4: 0
Data sent 124521


Server received data as:
//First data received which is exactly as sent and correct
Size Received: 126128
Byte 1: 176
Byte 2: 236
Byte 3: 1
Byte 4: 0
//Second data received is invalid and not as sent
Size Received: 1734438217
Byte 1: 73
Byte 2: 109
Byte 3: 97
Byte 4: 103

As you can see the first data I have added for you to give an idea that how data is sent and received but during the second data it is not what the client sent. Also do you notice that byte[] values received are invalid. I have no idea what is wrong and from where the server is filling up the byte[] values.
FYI the client sending and server is receiving data in a while(true) i.e. Continuously
Posted
Updated 9-Jan-23 6:44am

Start by not swallowing your exceptions: replace catch { } with something to log the problem. All you do at the moment is say "if it does something wrong, I don't care, ignore it" which means that the data you are sending could be complete rubbish and you don't know.
If you get a problem in your send, then the client gets "out of step" and it all falls over.

Think about it: if you send the datasize then fail, you will wait half a second and send another datasize then the valid data - so the lats four bytes of that will be assumed to be the datasize for the next block.

That would explain why it looks like bad size - it's "random data" which is supposed to be part of the image and because you swallow the exception you never know it's happened or why ...
 
Share this answer
 
Comments
Member 14623639 30-Dec-22 2:21am    
Actually the data is sent correctly from the client as you can see in the results on sent byte[] value from client. Also I tried logging exceptions as you said but it seems client is not throwing any exceptions and working correctly. I think the problem is with the server as it seems it's messing with the byte[] of datasize.
OriginalGriff 30-Dec-22 2:46am    
Prove it: Change the catch to log errors instead of swallowing them and see what happens ... all you know at the moment is "sending works sometimes" and "receiving gets the wrong data sometimes". You are assuming that because something works once, it'll always work. That's not necessarily the case, and since swallowing the exception provides a mechanism to silently cause your problem it's well worth dealing with to check.
Member 14623639 30-Dec-22 2:52am    
I said "Also I tried logging exceptions as you said but it seems client is not throwing any exceptions"
OriginalGriff 30-Dec-22 3:44am    
The client isn't, no - but the event swallowing is happening at the *server* ...
Member 14623639 30-Dec-22 4:09am    
Server is throwing "Exception of type 'System.OutOfMemoryException' was thrown." on byte[] data = new byte[size]; as the value I got is "1734438217".
My recommendation is to send/receive the "image data" in chunks instead of trying to push all the data at once into the socket. Use a MemoryStream to write the accumulated data.
 
Share this answer
 
Comments
Member 14623639 31-Dec-22 23:20pm    
Sure I will try to implement it.
I'm very late to the party here, and this is probably already resolved. Griff and Dave gave some good advise - but here are some thoughts anyway;

1.) You're running the client and server on separate machines? Don't do that yet. You're just developing this... run them both in the IDE, and set stops. Mouse over the variables and watch their values as your program runs.

2.) The only reason your server would be receiving invalid size bytes is if it's actually receiving image data instead - so your client and server's communication is falling out of sync, as Griff said. Run both applications in the IDE and set stops so you can watch communication and see it happen.

3.) Readability is everything. Try to make your code as clear as possible. Comment it for YOURSELF. You may come back to this code years later, and if it's a mess you may not understand what your looking at yourself. Writing clear code will make some bugs clear before you run it the first time. Begin by organizing the code in your functions.

4.) Don't create new objects in your send and receive functions. This is a great way to create a memory leak for yourself. Not even the
datasize = new byte[4]
create a buffer byte variable outside of your functions, and pass them to the function. Do the work in the buffer without creating anything new.

Hope this helps,
- Pete
 
Share this answer
 
Comments
Member 14623639 11-Jan-23 0:02am    
Hello Pete, thanks for your reply. I have noted your points and would definitely implement them in my program and also in my habits.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900