This message was discovered on microsoft.public.dotnet.general.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| Chris P. |
I have a C# application that connects to Perl application on a UNIX server. I am able to connect and communicate both directions with the server, but there are several occasions when it appears that the BinaryReader only reads part of the message sent by the server.
Here is the main flow of my application. 1. Open Socket 2. Read 4 byte integer 3. Read byte array that is the size of the integer in step 2. 4. Put message in collection 5. Repeat Steps 2 through 5
Simple enough? Where my problem occurs, is that sometimes step 3 reads fewer bytes than the integer that was read in step 2. For example, the integer in step 2 was 3564, but the string that was parsed was only 2756 bytes long. When we get back to the top of the loop, the integer in step 2 is 1014391148, which if you break it down byte by byte is the next 4 characters in the string. The app crashes because it "lost it's place." I thought by setting the socket as Blocking it would wait until it read the number of bytes in the array (This is how I've done similar things in Java), but it hasn't seemed to help. Also, I have tried to add Thread.Sleep(750) between step 2 and step 3. That seems to prevent most errors from occurring, but I am not happy with that being a solution.
Any suggestions?
Here is the way that I am declaring my socket and readers:
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp); socket.Blocking = true; socket.Connect(endPoint); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 0); stream = new NetworkStream(socket, FileAccess.ReadWrite, true); reader = new BinaryReader(stream); writer = new BinaryWriter(stream);
Here is my main loop:
while (!_stop) { msgLength = new byte[4]; if (reader.Read(msgLength,0,4) > 0) { // This stops 90% of errors, but is bad practice. // Thread.Sleep(750);
message = new byte[length]; if (reader.Read(message,0,(int)length) > 0) { serverMessage = enc.GetString(message,0,(int)length); putReceiveMessage(serverMessage); } } }
|
|
| |
| | |
|
|
|
|