2015-05-01 84 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连接相同。 –