2014-03-25 27 views
0

我正在編寫一個C#客戶端來連接到Node.JS服務器。事情工作正常,但有一點接收功能停止工作。我能夠確定訪問客戶端收到的字符串是凍結線程。一些代碼摘錄:C#異步客戶端 - 訪問字符串凍結接收線程

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
byte[] byteData = new byte[2048]; 

... setup socket connection ... 

socket.BeginReceive(byteData, 0, byteData.Length, 
    SocketFlags.None, new AsyncCallback(OnReceive), null); 

private void OnReceive(IAsyncResult ar) 
{ 
    socket.EndReceive(ar); 

    stringData = Encoding.ASCII.GetString(byteData).Trim(); 

    Console.WriteLine("Before string"); 
    Console.WriteLine(stringData); 
    Console.WriteLine("After string"); 

    // always ready to asynchronously receive 
    socket.BeginReceive(byteData, 0, byteData.Length, 
     SocketFlags.None, new AsyncCallback(OnReceive), null); 
} 

此輸出以下自收到時「OK」的Node.js:

Before string 
OK 

而且換行不,甚至連由控制檯寫的,因爲該系統輸出繼續直接在同一行上的'OK'後面。任何後續接收都不會顯示。我不知道可能是什麼原因造成的,我似乎無法找到其他人遇到這個問題。

回答

1

socket.EndReceive返回一個值,告訴您實際讀取的字節數。您需要獲得該值,並將它傳遞給GetString方法:

int bytesRead = socket.EndReceive(ar); 
stringData = Encoding.ASCII.GetString(byteData, 0, bytesRead); 

否則,GetString會嘗試將整個字符串轉換。這會給你所有的垃圾。您對Trim()的現有調用將刪除當前執行方式導致的尾部nul字節,但如果您將部分填充的緩衝區傳遞給下一個調用,那麼這樣做不會阻止您陷入垃圾。

這就是說,我沒有看到任何會導致事物鎖定的東西。你確定你沒有更改代碼的其他部分,並且導致了鎖定?

+0

是的,我確定它不是代碼的另一部分,因爲我使用了'git reset --hard HEAD',問題依然存在。這讓我懷疑Node.JS方面是否存在這個問題,但我不明白這會對客戶端造成怎樣的影響。 編輯:使用'bytesRead'修復它。我不知道爲什麼它以前,而不是現在,但我很感謝解決方案。 – BenJuan26

+0

@ BenJuan26:很高興解決了你的問題。知道緩衝區內容是很有意思的。我的假設是轉換整個2048字符緩衝區導致一些字符導致輸出的長時間延遲。例如,如果您創建了一串2048'BEL'字符('chr(7)'),然後輸出它,計算機將執行2,048個單獨的嘟嘟聲。這需要很長時間。 。 。 –