2011-04-19 96 views
0

我正在爲我的一個學校項目做這個。我試圖設計一個多線程服務器,接受客戶端使用數據庫(添加,刪除記錄等)。當我將客戶端連接到服務器時,我想要接收數據庫中的所有學生。如何通過tcp/ip協議發送一個包的長度

我訪問服務器端的數據庫,並將信息存儲在ArrayList中,我試圖通過網絡發送它。我對XMLserializing沒有任何知識,所以我試圖將arrayList中的每個字符串發送到客戶端。當我從服務器發送數據時,我有時會同時收到所有數據,有時候我不會,所以我的第一個猜測是我必須將我發送的數據分成一些長度的包。我不知道如何在包的開頭添加長度。難道它不是一回事嗎?也許我得到正確的長度,也許我沒有。

這是我的代碼;我沒有嘗試發送每個包的長度,因爲我不知道如何。我嘗試從服務器發送arraylist的長度,並從網絡流中多次讀取,但它不起作用(我在一個包中接收所有數據)。

服務器端:

private void HandleClient(object client) 
    { 
     try 
     { 
      ClientNo++; 

      TcpClient tcpClient = (TcpClient)client; 
      NetworkStream clientStream = tcpClient.GetStream(); 
      byte[] bytes = new byte[4096]; 
      int i; 
      // Robot r = new Robot(); 
      Protocol p = new Protocol(); 
      ArrayList ListaStudentiResponse = p.ExecuteQueryOnStudents("select * from studenti"); 
      byte[] Length = new byte[4]; 
      Length = System.Text.Encoding.ASCII.GetBytes(ListaStudentiResponse.Count.ToString()); 
      clientStream.Write(Length, 0, Length.Length); 
      foreach (String s in ListaStudentiResponse) 
      { 

       byte[] data = System.Text.Encoding.ASCII.GetBytes(s); 
       clientStream.Write(data, 0, data.Length); 

      } 


      tcpClient.Close(); 
      ClientNo--; 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 

    } 

客戶端:

private void connectToServerToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     tcpclient = new TcpClient(); 

     NetworkStream netStream; 
     try 
     { 
      tcpclient.Connect("localhost", 8181); 
      netStream = tcpclient.GetStream(); 
      Byte[] bytes = new Byte[10000]; 
      int readBytes = netStream.Read(bytes, 0, bytes.Length); 
      int Length =Int32.Parse(Encoding.ASCII.GetString(bytes, 0, readBytes)); 
      MessageBox.Show(Length.ToString()); 
      int i = 0; 
      while (i < Length) 
      { 
       i++; 
       Byte[] b = new Byte[10000]; 
       readBytes = netStream.Read(bytes, 0, bytes.Length); 
       String response = Encoding.ASCII.GetString(b, 0, readBytes); 
       MessageBox.Show(response); 


      } 

     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 

    } 
} 
+0

您應該匹配客戶端上的緩衝區長度。即分別使用長度爲4字節和10,000字節的緩衝區並記錄。 – Smudge202 2011-04-19 23:20:07

回答

0

這是我一直在使用它:

How to use the buffer on SocketAsyncEventArgs object

看接受的答案。第一次,這是使用一個比異步高效的呼叫完成端口。其次,我發現通過查看e.SocketError來發現故障的確切原因,很容易排除故障。

它的工作原理是爲了讓您的消息發送,附加帶有標題和預告片的消息。
所以當它收到消息時,它會檢查是否收到預告片。如果未收到預告片,它將繼續接收該客戶端,並將收到的消息附加到stringBuilder對象。收到預告片後,只需調用stringbuilder.toString()即可獲取整個內容。

相關問題