2009-07-18 33 views
6

Pracuję nad aplikacją klient/serwer Ruby TCP, używając GServer i TCPSocket. Wpadłem na problem, którego nie rozumiem. Mój klient TCPSocket pomyślnie łączy się z moim urządzeniem GServer, ale mogę wysyłać dane tylko za pomocą putów. Połączenia z TCPSocket.send lub TCPSocket.write nie powodują żadnych problemów. Czy jest jakaś magia, której mi brakuje?Ruby TCPSocket write nie działa, ale działa?

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

Ale jeśli mogę użyć zapisu lub wysłać ...

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

Dzięki za pomoc

Dodatkowe informacje:

  1. zachowanie jest takie samo na Linuksie & systemu Windows .
  2. Płukanie gniazda po zapisie nie zmienia zachowania.

Odpowiedz

4

Czy na pewno problem nie występuje po stronie serwera? Czy używasz jakiejś metody czytania, która oczekuje ciągu znaków lub czegoś kończącego się na "\ n"?

+0

Myślałem, że użyłem recvfrom po stronie serwera, ale okazało się, że używałem gets, który szuka znaku nowej linii. – nathan

2

Spróbuj wyraźnie spłukiwania:

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

ten sposób wyjście jest buforowane co najwyżej tylko do momentu, w którym zdecydujesz powinno być wysłane.

+1

Dziękuję, proszę, ale zobacz mój komentarz powyżej. Nie było żadnej różnicy podczas dzwonienia. – nathan

3

Z buforowaniem pod opieką we wcześniejszych postach, aby zająć się kwestią, czy dane są wysyłane, należy rozważyć przechwycenie danych w linii przy użyciu czegoś takiego jak wireshark. Jeśli dane, które wysyłasz, są widoczne na linii, serwer ich nie odbiera.

W przeciwnym razie, jeśli dane nie jedzie na linię, TCP może trzymać dane, aby uniknąć wysyłania jeden segment tylko kilka bajtów w nim (see Nagle's Algorithm). W zależności od dostawcy systemu operacyjnego lub dostawcy TCP możesz mieć inne zachowanie, ale większość stosów TCP obsługuje opcję TCP_NODELAY, która może pomóc w uzyskaniu danych w bardziej aktualny sposób.

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

Może to pomóc w debugowaniu, ale zazwyczaj nie powinno być pozostawione w kodzie produkcyjnym, jeśli przepustowość ma wyższy priorytet niż czas reakcji.

+1

netcat jest bardzo przydatnym narzędziem do testowania. "nc -v -n -l -p 12345" wykona serwer nasłuchujący na porcie 12345, który wydrukuje dane natychmiast po ich otrzymaniu. –

+0

'-l Błędem jest używanie tej opcji w połączeniu z opcjami -p, -s lub -z'' – 7stud

0

Witam, powód powinien być związany z tym faktem, dodać automatyczne LF i CRL do łańcucha. Jeśli chcesz użyć send lub napisać trzeba dodać im się tak na przykład, że byłoby:

tcp_client.send („Z \ r \ n”, 0)

0

miałem ten sam problem, więc po przeczytaniu tego gniazda musiałem jawnie usunąć ostatnie wystąpienie "\ n", wykonując następujące czynności:

client_socket.gets.gsub(/\n$/, '') 
Powiązane problemy