Ruby TCPSocket пишет не работает, но ставит ли? - PullRequest
6 голосов
/ 18 июля 2009

Я работаю над клиентским / серверным приложением Ruby TCP, используя GServer и TCPSocket. Я столкнулся с проблемой, которую не понимаю. Мой клиент TCPSocket успешно подключается к моему GServer, но я могу отправлять данные только с помощью пут. Вызовы TCPSocket.send или TCPSocket.write ничего не делают. Есть ли какая-то магия, по которой я скучаю?

tcp_client = TCPSocket.new( ipaddr, port )
tcp_client.puts( 'Z' ) # -> GServer receives "Z\n"

Но если я использую запись или отправку ...

tcp_client = TCPSocket.new( ipaddr, port )
tcp_client.write( 'Z' ) # -> nothing is received
tcp_client.send( 'Z' ) # -> nothing is received

Спасибо за помощь

Дополнительная информация:

  1. Поведение является одинаковым в Linux и Windows.
  2. Очистка сокета после записи не меняет поведение.

Ответы [ 5 ]

4 голосов
/ 20 июля 2009

Вы уверены, что проблема не на стороне сервера? Вы используете какой-то метод для чтения, который ожидает строку или что-то, заканчивающееся на "\ n"?

4 голосов
/ 21 июля 2009

С учетом буферизации, использовавшейся в предыдущих публикациях для решения вопроса о том, отправляются ли данные, рассмотрите возможность захвата данных в строке, используя что-то вроде wireshark . Если отправляемые вами данные отображаются в строке, сервер их не получает.

В противном случае, если данные не поступают в строку, TCP может удерживать данные, чтобы избежать отправки одного сегмента с несколькими байтами в нем ( см. Алгоритм Nagle ). В зависимости от вашей ОС или поставщика TCP вы можете вести себя по-разному, но большинство стеков TCP поддерживают опцию TCP_NODELAY, которая может помочь вывести данные более своевременно.

tcp_client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)

Это может помочь при отладке, но, как правило, его не следует оставлять в рабочем коде, если пропускная способность имеет более высокий приоритет, чем отзывчивость.

2 голосов
/ 19 июля 2009

Попробуйте явно сбросить:

tcp_client = TCPSocket.new( ipaddr, port )
tcp_client.write( 'Z' ) 
tcp_client.send( 'Z' ) 
tcp_client.flush

Таким образом, выходные данные буферизуются не более чем до того момента, когда вы решите, что они должны быть отправлены.

0 голосов
/ 18 июня 2014

У меня была такая же проблема, поэтому после прочтения сокета мне пришлось явно удалить последний экземпляр "\ n", выполнив следующее:

client_socket.gets.gsub(/\n$/, '')
0 голосов
/ 31 марта 2014

Привет, причина должна быть связана с тем, что автоматически добавляет LF и CRL к вашей строке. Если вы хотите использовать send или write, вам нужно добавить их самостоятельно, например, так:

tcp_client.send ("Z \ r \ n", 0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...