2

I have a program that sends 88 bytes of raw data (not a string) using NetworkStream.Read and NetworkStream.Write.

Byte number 58 happens to have the value 10 (new line). The receiving program instance stream stops reading once this byte is received acting like a ReadLine instead of Read for raw data.

The scenario is consistent that when I changed it to read 32 bytes at a time, it read 32 then 26 (total of 58) stopping at the same byte.

This is when I run the two program instances on different machines connected through the internet using port 21. When I run both instances on the same machine, the whole 88 bytes are received with no problems.

I will use Network Monitor to see where the 30 bytes get lost, but I thought to ask here for suggestions or if someone faced a similar problem.

Edit: Here's the code:

Here is the code. It reads data from one stream and writes them to the other working both ways: `

class ProxyConnection
{        
 private NetworkStream clientStream;
 private NetworkStream serverStream;
 public ProxyConnection()
 {
..            clientStream = tcpClient.GetStream();
            serverStream = tcpServer.GetStream();
..}

 private void RouteFromClientToServer()
 {
   Message message;
   while (true)
   {
     try
     {
       message = ReadMessageFromClient();
       ValidateMessage(message);
       SendMessageToServer(message);
     }
     catch(IOException e)
     {
      Logger.getInstance().log(e.Message);
      break;
     }
    }
}
        private Message ReadMessageFromClient()
        {
            Message message = new Message();
            message.bytes = new byte[MESSAGE_SIZE];
            message.bytesCount = clientStream.Read(message.bytes, 0, MESSAGE_SIZE);
            Logger.getInstance().log("Size ( " + message.bytesCount + " ) From Client");
            return message;
 }



    private void SendMessageToServer(Message message)
    {      
        serverStream.Write(message.bytes, 0, message.bytesCount);
        Logger.getInstance().log("Size ( " + message.bytesCount + " ) To Server");
        serverStream.Flush();
    }


}
Jeremy McGee
  • 24,842
  • 10
  • 63
  • 95
  • 2
    Can you post the code you're using to read the data? Are you using a proxy of some kind between the machines? – Jeremy McGee Dec 28 '11 at 13:52
  • 2
    Could it read the rest if you did another read? – cHao Dec 28 '11 at 13:53
  • @JeremyMcGee I added the code. One of the machines is at my workplace so there could be a proxy. – Ahmed Nasser Dec 28 '11 at 15:12
  • @cHao No it blocks.. When I read 32 at a time it reads 32 then 26 then blocks – Ahmed Nasser Dec 28 '11 at 15:12
  • @Ahmed: This code isn't enough to replicate the issue. The code as we see it should not have any issues, unless some code we don't see here messes with the streams. I just managed to implement half a proxy with it. – cHao Dec 28 '11 at 18:31
  • @chao Apparently the problem was that The client was behind a proxy that would manipulate the data on its own. I was using port 21 (originally the FTP port) so there was probably some special handling by the workplace proxy on that port. When I changed to port 1863 everything worked like a charm :) . Thank you very much for your time, it is really appreciated. – Ahmed Nasser Dec 29 '11 at 11:56
  • @jeremymcgee Thank you for your time. It was a proxy problem. Thank you for your help. – Ahmed Nasser Dec 29 '11 at 11:56
  • Ah yes. That's worth an answer, I'll edit your question so other people coming from Google in future have half a chance of finding this. This could cause hours of debugging! – Jeremy McGee Dec 29 '11 at 12:00

2 Answers2

0

TCP sockets don't particularly care how many bytes you want to send or receive at a time. If the data or space is available, it will receive or send as much as you can handle. If there's no space or data, the send or receive can block til there's something it can do. But if the buffer has space for 10 bytes and you're sending 50, then the socket will happily stuff 10 bytes into the buffer and say "10 bytes sent. Try sending the rest in a bit." Likewise, if there's 10 bytes available and you want 50, the socket says "Here's 10. Make do til i have more." A subsequent receive or send on the socket will typically block til there's more data or space, then read or write as much as is available at that time. That's why they return how much data they managed to shuffle around.

It's quite possible that there's some magic (like auto-flushing on sending a 10) happening to make it easier to handle text over the stream, since that's such a common use case. But if you read again, you should get more data. Unless the read returns 0 bytes -- that typically means the connection's been closed, and that you're not shutting down the socket before you close/dispose it.

cHao
  • 84,970
  • 20
  • 145
  • 172
  • Here is the class. It reads data from one stream and writes them to the other working both ways: – Ahmed Nasser Dec 28 '11 at 15:01
  • Your code as posted didn't work, but once i added code to set up the streams and added a stub `ValidateMessage` function and `Message` and `Logger` classes, it works fine. It doesn't have any issues that'd keep it from delivering everything, although there's no guarantee it'll transfer in chunks of any given size. The problem is elsewhere...be it in code you haven't posted, or in the client or server. – cHao Dec 28 '11 at 21:30
0

Which port are you using? Is there a proxy server?

Specifically, if you're using port 21 (FTP) some proxy servers have special-case handling of passive FTP. I believe this requires the proxy to scan the traffic - so in particular if the commands are invalid then you'll see the proxy close the socket connection.

The workaround is... use a different port.

Jeremy McGee
  • 24,842
  • 10
  • 63
  • 95