Ruby ruby 的 TCPSocket 用 read/write 不能通信,用 gets/puts 就可以

yakczh · 2012年11月14日 · 最后由 flowerwrong 回复于 2016年10月31日 · 7225 次阅读

上代码 server

require 'socket'                 
server = TCPServer.open('127.0.0.1',2000)     

client = server.accept        

loop {  
    str=client.read  
    puts str  
    client.write(str)  
}   
client.close    

client

require 'socket'        

host = '127.0.0.1'  
port = 2000  
msg="\0x48\0x0a\0x0d"  
s = TCPSocket.open(host, port)  
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)  
loop  do   
    send = s.write(msg)  
    s.flush  
    puts   msg  
    resp = s.read  
    puts resp  
    sleep 1  
end   

google 了一下,别人也有相同的问题, 按照这上面说的 http://stackoverflow.com/questions/1147852/ruby-tcpsocket-write-doesnt-work-but-puts-does 加上 s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) 和 flush 也不管用

用 ```ruby 把代码排一下吧。搞 ruby 的一定要注意可读性。

read 不给参数就要读到 EOF 才返回,你可以用 read 3 读 3 字节

p.s. 很多 tcp 之上的协议都是基于换行的,例如 http, telnet. 如果想要实现非换行的协议,可以参照 chunked http 的传输,在每段内容之前加上长度,然后客户端通过长度决定读多少个字节。

#2 楼 @luikore 你的解释是对的,我也遇到了类似的问题。多谢

#2 楼 @luikore

require 'socket'                 
server = TCPServer.open('127.0.0.1',3000)     
loop {  

      client = server.accept        
      buffer = ""
      while  1 do
             #puts client.eof  
              break if  client.eof?

              buffer=client.gets
              puts buffer
      end  


      client.close
}   

curl http://localhost:3000/ 一直死循环,打印 client.eof 始终是 false 用浏览器也是一样

@tablecell 这里你没法用 eof? 去查,因为只要连接没关闭它都还没 eof, 但是作为一个 http 请求,客户端还在等响应,客户端不会现在就关请求的

非换行协议设计可以参考tlv, 才看到是 2012 年的贴子。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号