0
对于需要实施TCP服务器的项目。但过了一段时间,我看到有时候我正在丢失信息。这对我来说是一个惊喜,因为我总是被告知TCP不会丢包。与TCPServer丢失的邮件
所以我写了两个小脚本来测试邮件的接收情况,并且我看到我失去了一些,即使它是我能做的最简单的代码。
为了让示例变得简单,我为每个连接创建了一个不同的线程,但我的生产代码不会这样(它将是一个像NGNIX一样工作的线程池)。
这里是服务器的代码:
require 'socket'
require 'thread'
require 'timeout'
LIMIT = 100
def get_message (client)
message = 'nothing'
begin
Timeout::timeout(1) do
message = client.gets
end
rescue
message = 'timeout'
end
unless message == nil
message.chomp!
end
message
end
server = TCPServer.new(9000)
queue_message, queue_empty, queue_nil, queue_nothing, queue_timeout = Queue.new, Queue.new, Queue.new, Queue.new, Queue.new
threads = []
(1..LIMIT).each do
threads << Thread.start(server.accept) do |client|
counter = 0
while counter != LIMIT do
message = get_message(client)
case message
when nil
queue_nil << message
break
when ''
queue_empty << message
when 'nothing'
queue_nothing << message
when 'timeout'
queue_timeout << message
else
queue_message << message
counter += 1
end
end
client.close
end
end
threads.each {|t| t.join}
size = queue_message.size
counter = 0
check = Array.new(LIMIT){Array.new(LIMIT)}
until queue_message.empty?
message = queue_message.pop.split '::'
check[message[0].to_i][message[1].to_i] = 1
end
(0..LIMIT - 1).each do |i|
(0..LIMIT - 1).each do |j|
if check[i][j] == nil
puts "#{j}::#{i}"
counter += 1
end
end
end
puts '--------------------------------------'
puts 'Threads are finished'
puts "messages: #{size}"
puts "missing: #{counter}"
puts "nil: #{queue_nil.size}"
puts "empty: #{queue_empty.size}"
puts "nothing: #{queue_nothing.size}"
puts "timeout: #{queue_timeout.size}"
puts '--------------------------------------'
这是客户端的代码:
require 'socket'
LIMIT = 100
def get_message (client)
message = ''
begin
Timeout::timeout(GETS_TIMEOUT_SPECS) do
message = client.gets
end
unless message == nil
message.chop!
end
end
message
end
threads = []
client = []
(0..LIMIT - 1).each do |j|
threads << Thread.new do
client[j] = TCPSocket.new('localhost', 9000)
(0..LIMIT - 1).each do |i|
message = "#{j}::#{i}"
client[j].puts message
puts message
sleep 1
end
client[j].close
end
end
threads.each {|t| t.join}
最后,这是我得到的输出示例:
--------------------------------------
Threads are finished
messages: 8230
missing: 1770
nil: 100
empty: 557
nothing: 0
timeout: 2258
--------------------------------------
有时根本没有损失。 那么我的信息在哪里丢失?