2015-05-01 88 views
-1

我正在寫一個perl腳本來與android GCM CCS進行通信。我的腳本如下所示:Perl IO :: Socket :: SSL持久性TCP連接

use IO::Socket::SSL; 

my $client = IO::Socket::SSL->new('gcm.googleapis.com:5236') 
    or die "error=$!, ssl_error=$SSL_ERROR"; 

print $client '<stream:stream to="gcm.googleapis.com" version="1.0" 
#xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams"/>'; 
print <$client>; 
print $client '<auth mechanism="PLAIN" 
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb 
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>'; 

if(!<$client>){ 
    print "Auth error\n"; 
} else { 
    print <$client>; 
} 

在套接字上寫入第一個請求之後,我從google服務器收到預期的響應。而且我無法使用print 打印服務器響應。但是,在寫入第二個請求後,我沒有收到任何迴應。看起來連接在第一次請求和響應之後被關閉。如何通過打開的TLS連接發送多個請求並接收服務器響應?

更新

我得到下面的,如果我打開調試

DEBUG: .../IO/Socket/SSL.pm:1464: new ctx 145780168 
DEBUG: .../IO/Socket/SSL.pm:332: socket not yet connected 
DEBUG: .../IO/Socket/SSL.pm:334: socket connected 
DEBUG: .../IO/Socket/SSL.pm:347: ssl handshake not started 
DEBUG: .../IO/Socket/SSL.pm:390: Net::SSLeay::connect -> 1 
DEBUG: .../IO/Socket/SSL.pm:445: ssl handshake done 
    write_all VM at entry=vm_unknown 
    written so far 124:124 bytes (VM=vm_unknown) 
    write_all VM at entry=vm_unknown 
    written so far 188:188 bytes (VM=vm_unknown) 
    got 147:0 bytes (VM=vm_unknown). 
    got 197:147 bytes (VM=vm_unknown). 
    got 0:344 bytes (VM=vm_unknown). 
    got 0:0 bytes (VM=vm_unknown). 
DEBUG: .../IO/Socket/SSL.pm:1201: SSL read errorerror:00000000:lib(0):func(0):reason(0) 

<stream:stream from="gcm.googleapis.com" id="626DAFBE58C7FD0D" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism><mechanism>PLAIN</mechanism></mechanisms></stream:features>Auth error 
DEBUG: .../IO/Socket/SSL.pm:1500: free ctx 145780168 open=145780168 
DEBUG: .../IO/Socket/SSL.pm:1508: OK free ctx 145780168 

回答

2

DEBUG: .../IO/Socket/SSL.pm:1201: SSL read errorerror:00000000:lib(0):func(0):reason(0)

服務器關閉了連接。如果服務器決定關閉連接,則無法保證連接處於打開狀態併發送更多內容。關閉可能與您收到的驗證錯誤有關。

另外:

print <$client>; 

要調用在列表環境中<>操作。這意味着它會嘗試從套接字讀取全部行。由於全部行僅在服務器關閉連接時完成(這是TCP的工作方式,與TLS無關),因此您需要等待直到服務器關閉。

+0

嗨,謝謝你的回覆。身份驗證錯誤來自不是來自服務器的if塊。我怎樣才能部分閱讀?正如你可以看到即時通訊嘗試建立與服務器的雙向通信(通過TLS)的任何想法我可以做什麼?這裏有一個與Google CCS服務器連接的python示例,對於這個Google不關閉連接。所以我一定是在客戶端做錯了, https://developer.android.com/google/gcm/ccs.html#python –

+0

由於服務器關閉了連接,所以認證錯誤來自if塊。並且服務器關閉了連接,因爲您在'print <$client>'內等待,直到服務器關閉(列表上下文)。對於部分讀取,您可以使用更好的sysread。然後你必須知道消息什麼時候結束,即做XML解析的東西等等。再次,這與TLS無關,並且與正常的TCP連接相同。 –