yılında iki yönlü SSL soket oluşturabilir, ama aynı zamanda kullanıcıların bir yöntemi çağırarak veri göndermek için izin verir.nasıl bir sunucuya bağlanır ve veri bekler bir istemci Ruby kütüphane oluşturma çabası Ruby
kullandığım mekanizma bir soket çifti başlatır bir sınıf var şöyle şudur:
def initialize
@pipe_r, @pipe_w = Socket.pair(:UNIX, :STREAM, 0)
end
Ben geliştiriciler sunucuya veri göndermek için arama yapılmasına izin yöntem aşağıdaki gibidir:
Sonradef send(data)
@pipe_w.write(data)
@pipe_w.flush
end
ben sunucuya bağlı bir socket
arasından seçim ayrı bir iş parçacığı, bir döngü var ve @pipe_r
den:
def socket_loop
Thread.new do
socket = TCPSocket.new(host, port)
loop do
ready = IO.select([socket, @pipe_r])
if ready[0].include?(@pipe_r)
data_to_send = @pipe_r.read_nonblock(1024)
socket.write(data_to_send)
end
if ready[0].include?(socket)
data_received = socket.read_nonblock(1024)
h2 << data_received
break if socket.nil? || socket.closed? || socket.eof?
end
end
end
end
Bu, güzel bir şekilde ancak yalnızca örnek olarak normal TCPSocket
ile çalışır. Ben ancak the IO.select docs uyarınca, bunun yerine bir OpenSSL::SSL::SSLSocket
kullanmak gerekir:
iyi yolu IO.select vb read_nonblock, write_nonblock gibi beklememe yöntemlerle sonra yürütmesini Kullanmak
[...]
Özellikle nonblocking yöntem ve IO.select gibi OpenSSL :: SSL :: SSLSocket gibi nesneler gibi IO için tercih edilir bir kombinasyonu.
Buna göre ne zaman döngü içinde ben bu yüzden 2 farklı IO nesneler arasından seçim yapabilirsiniz önce kullanın ederken, Nonblocking yöntemlerle sonra IO.select
çağırmanız gerekir.
bir SSL soketi ile IO.select
nasıl kullanılacağı konusunda verilen örnektir:
begin
result = socket.read_nonblock(1024)
rescue IO::WaitReadable
IO.select([socket])
retry
rescue IO::WaitWritable
IO.select(nil, [socket])
retry
end
Ancak bu IO.select
bir tek IO nesnesi ile kullanıldığında durumunda çalışır.
Sorum şu: nasıl bir SSL soketi ile benim önceki örnek çalışması yapabilir, ben de @pipe_r
ve socket
nesnelerden seçmek gerektiğini verilen?
DÜZENLEME: Ben ancak boşuna ne @ steffen-ullrich önerdi denedim. Aşağıdaki benim testler kullanılarak geçmesi yapmak başardı:
loop do
begin
data_to_send = @pipe_r.read_nonblock(1024)
socket.write(data_to_send)
rescue IO::WaitReadable, IO::WaitWritable
end
begin
data_received = socket.read_nonblock(1024)
h2 << data_received
break if socket.nil? || socket.closed? || socket.eof?
rescue IO::WaitReadable
IO.select([socket, @pipe_r])
rescue IO::WaitWritable
IO.select([@pipe_r], [socket])
end
end
Bu kadar kötü görünmüyor, ancak herhangi bir giriş açığız.
Teşekkür ederim @ steffen-ullrich, bu çok açık bir cevaptır. Maalesef, select seçeneğini kullanmadan önce bekleyen yöntemi kullanmayı denedim ve her zaman 0 bayt olduğunu öğreniyorum. Ayrıca nonblock_read (32768) denedim ve bu da hile değil. Biraz daha deneyeceğim. – ostinelli
Bu cevabı kabul edeceğim, çünkü bu sorunları çözmek için doğru yolu açıklığa kavuşturuyor. Tekrar teşekkürler! – ostinelli