में मैं दो-तरफा एसएसएल सॉकेट कैसे बना सकता हूं, मैं एक क्लाइंट रूबी लाइब्रेरी का निर्माण कर रहा हूं जो सर्वर से कनेक्ट होता है और डेटा की प्रतीक्षा करता है, लेकिन उपयोगकर्ताओं को विधि को कॉल करके डेटा भेजने की अनुमति देता है।रूबी
तंत्र मैं उपयोग करते हैं, एक वर्ग है कि एक सॉकेट जोड़ी initializes है तो तरह है:
def initialize
@pipe_r, @pipe_w = Socket.pair(:UNIX, :STREAM, 0)
end
विधि है कि मैं डेवलपर्स सर्वर से डेटा भेजने के लिए कॉल करने की अनुमति इस तरह दिखता है:
def send(data)
@pipe_w.write(data)
@pipe_w.flush
end
तो मैं एक अलग थ्रेड, जहां मैं एक socket
सर्वर से जुड़ा से चयन में एक पाश है और @pipe_r
से:
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
यह उदाहरण के अनुसार, लेकिन केवल सामान्य TCPSocket
के साथ खूबसूरती से काम करता है। मैं तथापि के रूप में प्रति the IO.select docs, बजाय एक OpenSSL::SSL::SSLSocket
उपयोग करने की आवश्यकता: IO.select ऐसे read_nonblock, write_nonblock, आदि के रूप nonblocking तरीकों के बाद यह लागू है उपयोग करने के लिए
सबसे अच्छा तरीका है
[...]
विशेष रूप से, ओपनएसएसएल :: एसएसएल :: एसएसएलएसकेट जैसी वस्तुओं जैसे आईओ के लिए गैर-ब्लॉकिंग विधियों और IO.select का संयोजन पसंद किया जाता है।
इस के अनुसार, मैं nonblocking तरीकों के बाद IO.select
कॉल करने के लिए, जबकि मेरी पाश में मैं इसका इस्तेमाल से पहले तो मैं 2 अलग आईओ वस्तुओं से चुन सकते हैं की जरूरत है।
कैसे एक SSL सॉकेट के साथ IO.select
उपयोग करने के लिए दिए गए उदाहरण है:
begin
result = socket.read_nonblock(1024)
rescue IO::WaitReadable
IO.select([socket])
retry
rescue IO::WaitWritable
IO.select(nil, [socket])
retry
end
हालांकि इस केवल तभी कारगर साबित IO.select
एक एकल आईओ वस्तु के साथ प्रयोग किया जाता है।
मेरा प्रश्न है: मैं अपने पिछले उदाहरण को एसएसएल सॉकेट के साथ कैसे काम कर सकता हूं, यह देखते हुए कि मुझे @pipe_r
और socket
ऑब्जेक्ट्स दोनों से चयन करने की आवश्यकता है?
संपादित करें: मैंने कोशिश की है कि @ स्टीफन-औलिच ने सुझाव दिया है, हालांकि इसका कोई फायदा नहीं हुआ। मैं निम्नलिखित मेरी परीक्षण का उपयोग कर पारित कराने में सफल रहा:
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
यह इतना बुरा नहीं लगती है, लेकिन किसी भी इनपुट का स्वागत है।
धन्यवाद @ स्टीफन-औलिच, यह एक बहुत ही स्पष्ट उत्तर है। दुर्भाग्यवश मैंने चयन का उपयोग करने से पहले लंबित विधि का उपयोग करने का प्रयास किया है और मुझे हमेशा यह मिलता है कि 0 बाइट उपलब्ध हैं। मैंने nonblock_read (32768) भी कोशिश की है और यह चाल भी नहीं है। कुछ और कोशिश करेंगे। – ostinelli
इस उत्तर को स्वीकार करेगा क्योंकि यह इन मुद्दों को हल करने में सही तरीके से स्पष्ट करता है। फिर से धन्यवाद! – ostinelli