2010-07-03 30 views
-1

我的程序做的是,首先連接接受,服務器發送數據 客戶端接收再發送(Datasize不變) 服務器收到它然後再發回....這個循環繼續。 ..爲BeginReceive提供的字節

當服務器第二次收到數據時endreceive()返回的int;是0

雖然我已經找到了解決辦法,但我不知道爲什麼,這實際上解決問題

我讀somehewhere,有一些所謂的「髒」緩衝:■

所以我所做的就是。

//added line 
data = new byte[DataSize]; 

//now index works fine :s 
int index = socket.endreceive(result); 

以前我是爲發送重用byte[] data和接收不改變它的內容,發送數據全部爲零

和它的工作:)

MSDN犯規幫助我有或我錯過了somwthing? MSDN Link

這是總結代碼

private void OnSendCallBack(IAsyncResult result) 
    { 
     int id_client = (int)result.AsyncState; 
     try 
     { 

      int index = clientInfo[id_client].client.EndSend(result); 

      clientInfo[id_client].offsetSend += index; 
      if (index == 0) 
      { 
       Console.WriteLine("Index == 0"); 
       return; 
      } 
      else if (clientInfo[id_client].offsetSend < DataSize) 
      { 
       clientInfo[id_client].dataToSend = DataSize - clientInfo[id_client].offsetSend; 
       clientInfo[id_client].client.BeginSend(data, clientInfo[id_client].offsetSend, clientInfo[id_client].dataToSend, SocketFlags.None, RecieveCallBack, id_client); 
      } 
      else 
      { 
       clientInfo[id_client].offsetSend = 0; 
       clientInfo[id_client].dataToSend = DataSize; 
       //************************************* 
       data = new byte[DataSize]; // THIS IS THE PROBLEM HERE 
       //************************************* 
       clientInfo[id_client].client.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallBack, id_client); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Send: " + ex.Message); 
     } 
    } 

private void RecieveCallBack(IAsyncResult result) 
    { 
     int id_client = (int)result.AsyncState; 

     try 
     { 

      int index = clientInfo[id_client].client.EndReceive(result); 

      //byte[] buffer = new byte[DataSize]; 
      //int received = clientInfo[id_client].client.Receive(buffer); 

      clientInfo[id_client].offsetRec += index; 
      if (index == 0) 
      { 
       index = clientInfo[id_client].client.EndReceive(result); 
       Console.WriteLine("Index == 0"); 
       return; 
      } 
      else if (clientInfo[id_client].offsetRec < DataSize && clientInfo[id_client].offsetRec != 0) 
      { 
       clientInfo[id_client].dataToReceive = DataSize - clientInfo[id_client].offsetRec; 
       clientInfo[id_client].client.BeginReceive(data, clientInfo[id_client].offsetRec, clientInfo[id_client].dataToReceive, SocketFlags.None, RecieveCallBack, id_client); 
      } 
      else 
      { 
       clientInfo[id_client].offsetRec = 0; 
       clientInfo[id_client].dataToReceive = DataSize; 

       if (clientInfo[id_client].RunNumber < RounCount) 
       { 
        clientInfo[id_client].RoundTripStat.EndSample(); 
        clientInfo[id_client].RoundTripStat.BeginSample(); 
        clientInfo[id_client].client.BeginSend(data, 0, data.Length, SocketFlags.None, OnSendCallBack, id_client); 
       } 

       Close(id_client); 
      } 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Server: " + ex.Message); 
     } 
    } 

我提供SendCallback的代碼和接收回調,你可以看到一個非同步命令正在等待一次一個

回答

1

EndReceive()返回0,如果有沒有更多的數據要接收,並且套接字已關閉(即不再接收數據)。

從您提到的文檔:

如果遠程主機關閉與關機方法Socket連接,以及所有可用的數據已經被接收,該EndReceive方法將立即完成並返回零個字節。

你一般不應重複使用相同的緩衝區用於發送和接收 - 你最終會向您發送收到的任何數據,如果你有重疊的發送和接收異步調用它會在一個非常結束奇怪的狀態,可能。

如果您一次只執行一項操作,那麼「共享」緩衝區是唯一安全的,並且您確保在編寫時確實具有您想要的數據,並在其中明確設置。

+0

是的,我一次執行一個操作,但是,在接收之前,如果我不做data = new byte [DataSize] ...我從EndReceive(...)和套接字標誌接收0; 'Connected'會自動設置爲false:s – 2010-07-06 05:46:38

+0

@KiNGPiN:這聽起來很奇怪 - 你確定這不是因爲你發送的數據不正確嗎?一個簡短但完整的程序演示這個問題在這裏真的很有幫助。 – 2010-07-06 06:01:55

+0

我已經更新了代碼片段的問題,正如你可以在SendCallBack中看到的那樣,我啓動了BeginReceive ...一旦數據已經收到,發送只會被再次調用 並且代碼很簡單,沒有任何數據操作 – 2010-07-08 13:28:14