You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby TCPServer双向数据传输时连接冻结问题如何解决?

Ruby TCPServer双向通信连接冻结问题解决方案

问题根因

  • 客户端发送数据后未告知服务端数据传输已结束,服务端的while line = session.gets会持续阻塞等待新输入,无法进入返回响应的逻辑
  • 客户端发送完数据后直接进入读循环等待服务端返回,双方进入死等状态,只有客户端进程终止、连接断开时,服务端的gets才会返回nil退出循环
  • 原服务端代码中存储接收数据的test变量定义在连接循环外层,多次连接会出现数据累加污染的问题

最简修复方案(单次通信场景)

仅需在客户端发送完数据后关闭写通道,通知服务端数据已全部传输完成即可:

修改后的client.rb

require "socket"

socket = TCPSocket.open("localhost", 1234)
socket.puts "Sending data.." # 向服务端发送数据
# 新增:关闭写通道,告知服务端没有更多数据要发送
socket.close_write
while(line = socket.gets)
  puts line
end # 打印服务端响应
socket.close

优化后的server.rb(修复数据累加问题)

require "socket"
server = TCPServer.new 1234

loop do
  session = server.accept
  puts "Entering while loop."
  test = "" # 将变量挪到连接循环内,每次新连接清空数据
  while line = session.gets
    puts "Inside while loop"
    test << line
  end
  puts "Finished reading data"
  puts "Data received - #{test}" # 读取客户端发送的数据
  session.puts "Time is #{Time.now}" # 用puts代替write自动加换行,避免客户端读行阻塞
  session.close
end

长连接复用场景方案(约定传输结束标记)

如果需要保持连接多次双向通信,可以约定特定标记作为单次传输结束的标识,不需要频繁关闭通道:

server.rb

require "socket"
server = TCPServer.new 1234

loop do
  session = server.accept
  puts "Entering while loop."
  test = ""
  while line = session.gets
    # 遇到约定的结束标记就退出当前读循环
    break if line.chomp == "__END_OF_MSG__"
    puts "Inside while loop"
    test << line
  end
  puts "Finished reading data"
  puts "Data received - #{test}"
  session.puts "Time is #{Time.now}"
  # 此处如果需要继续复用连接处理后续请求,不要调用session.close
  session.close
end

client.rb

require "socket"

socket = TCPSocket.open("localhost", 1234)
socket.puts "Sending data.."
# 发送约定的结束标记,告知服务端本次数据传输完成
socket.puts "__END_OF_MSG__"
while(line = socket.gets)
  puts line
end
# 需要发送更多数据可以继续写socket,不需要重建连接
socket.close

内容的提问来源于stack exchange,提问作者SantiArias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 04:54:07