NetworkStream на порту 21 (FTP) прекращает чтение, когда получает байт со значением 10 (символ новой строки) - PullRequest
2 голосов
/ 28 декабря 2011

У меня есть программа, которая отправляет 88 байтов необработанных данных (не строки), используя NetworkStream.Read и NetworkStream.Write.

Байт номер 58 имеет значение 10 (новая строка). Поток экземпляра принимающей программы прекращает чтение после получения этого байта, действующего как ReadLine вместо Read для необработанных данных.

Сценарий последовательный, что когда я изменил его на чтение 32 байта за раз, он читал 32, а затем 26 (всего 58), останавливаясь на том же байте.

Это когда я запускаю два экземпляра программы на разных компьютерах, подключенных через Интернет, используя порт 21. Когда я запускаю оба экземпляра на одном компьютере, все 88 байтов принимаются без проблем.

Я буду использовать Network Monitor, чтобы увидеть, где теряются 30 байтов, но я подумал спросить здесь, есть ли предложения или кто-то сталкивался с подобной проблемой.

Редактировать: Вот код:

Вот код. Он читает данные из одного потока и записывает их в другой, работая в обоих направлениях: `

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();
    }


}

Ответы [ 2 ]

0 голосов
/ 29 декабря 2011

Какой порт вы используете?Есть ли прокси-сервер?

В частности, если вы используете порт 21 (FTP), некоторые прокси-серверы имеют специальную обработку пассивного FTP.Я считаю, что для проверки трафика требуется прокси-сервер, поэтому, в частности, если команды недействительны, прокси закроет соединение с сокетом.

Обходной путь ... используйте другой порт.

0 голосов
/ 28 декабря 2011

TCP сокеты не особенно заботятся о том, сколько байтов вы хотите отправлять или получать одновременно. Если данные или пространство доступно, они получат или отправят столько, сколько вы можете обработать. Если нет места или данных, отправитель или получатель могут заблокировать, пока он что-то может сделать. Но если в буфере есть место для 10 байтов, а вы отправляете 50, сокет с радостью вставит 10 байтов в буфер и скажет: «10 байтов отправлено. Попробуйте отправить остальные немного». Аналогично, если доступно 10 байтов, а вы хотите 50, сокет говорит: «Вот 10. Сделайте, пока у меня будет больше». Последующее получение или отправка на сокете, как правило, будет блокировать, пока будет больше данных или пространства, а затем будет считывать или записывать столько, сколько доступно в то время. Вот почему они возвращают, сколько данных им удалось перетасовать.

Вполне возможно, что происходит какое-то волшебство (например, автоматическая очистка при отправке 10), чтобы упростить обработку текста в потоке, поскольку это такой распространенный случай использования. Но если вы прочитаете снова, вы должны получить больше данных. Если чтение не возвращает 0 байтов - это обычно означает, что соединение было закрыто, и что вы не закрываете сокет, прежде чем закрывать / утилизировать его.

...