2012-06-08 141 views
1

我通常是一个.net开发(不要伤害我!),所以请原谅我在这里做:)Groovy的TCP客户端挂

我有.NET编写一个TCP监听任何真正愚蠢的错误,这收到xml并返回响应。我正在尝试在groovy中为它编写一个客户端,这样我就可以使用loadUI加载测试。这是我到目前为止:

def s = new Socket("10.208.24.59", 9061); 
s.withStreams { inStream, outStream -> 
    def reader = inStream.newReader() 
    def responseText = reader.readLine() 
    outStream << "Hello test server" 
    println "response = $responseText" 
} 
s.close(); 

我在eclipse中调试,它挂在withStreams行。我应该接受的是一个“消息不是XML”的消息,我可以通过telnet得到罚款。

任何想法我做错了什么?

更新 我只是尝试这样做,而不是withStreams关闭:

def r = new BufferedReader(new InputStreamReader(s.getInputStream())); 
def w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
w.write("Hello test server 2"); 
w.flush(); 
println r.readLine(); 
w.flush(); 
w.close(); 

它现在挂在的println r.readLine()调用

再次更新

事实证明,这是远程服务关闭的问题(或者更重要的是 - 不是关闭)流。 .net和我们的大型机都正确地处理它,但groovy脚本并不快乐。我已经修复了这个服务,脚本现在运行得很开心,值得记住任何碰到类似问题的人。

+0

我的猜测是服务器保持连接打开,所以缓冲读者没有按不知道返回是好事(并阻止等待更多数据)。另外,在获取responseText之前不应该使用''Hello测试服务器'吗? –

+0

好的,但可能会有坏服务或连接断开。所以,在常规,如何实现超时读取健壮的客户端? – Massimo

回答

3

=====更新====

嘿克里斯;

尝试将套接字写入流处理器之外。自Groovy leftShifted以来,您可以直接在插座上直接输出插座类。此外,不直接相关,但有助于调试,将套接字读取超时,以便您的线程不会无休止地阻塞。

def s = new Socket("10.208.24.59", 9061); 
s.setSoTimeout(3000); 
s << "Hello test server"; 
s.withStreams { inStream, outStream -> 
    def reader = inStream.newReader() 
    def responseText = reader.readLine() 
    println "response = $responseText" 
} 
s.close() 

===== /更新====

的问题是,newReader块等待您的服务器的输出。请参阅下面的堆栈跟踪。由于您永远无法发送您的请求,因此服务器没有响应。简而言之,在使用单线程发送请求之前不要发出监听。更改您的代码这一点,它应该工作:

def s = new Socket("10.208.24.59", 9061); 
s.withStreams { inStream, outStream -> 
    outStream << "Hello test server" // send request first 
    def reader = inStream.newReader() 
    def responseText = reader.readLine()  
    println "response = $responseText" 
} 
s.close(); 

的等待线程的堆栈跟踪看起来是这样的:

Stack trace: 
java.net.SocketInputStream.socketRead0(Native Method) 
java.net.SocketInputStream.read(SocketInputStream.java:129) 
sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) 
sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) 
sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) 
    - locked [email protected] 
java.io.InputStreamReader.read(InputStreamReader.java:167) 
java.io.BufferedReader.fill(BufferedReader.java:136) 
java.io.BufferedReader.readLine(BufferedReader.java:299) 
    - locked [email protected] 
java.io.BufferedReader.readLine(BufferedReader.java:362) 
java_io_BufferedReader$readLine.call(Unknown Source) 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) 
+0

有意义,但仍然悬在同一点 - 它似乎挂在withStreams行,在它关闭任何东西之前。感谢您的详细回复! –

+0

查看更新的答案。 – Nicholas

+0

仍然完全相同 - 它挂在withStreams行(或超时如果我包含超时命令。我可以看到请求通过服务器日志,并且“请求文本不是XML格式”响应被发回奇怪的是,我们很幸运地从各种客户端运行,几乎准备好放弃LoadUI作为测试工具 –