2012-06-08 145 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作爲測試工具 –