2017-01-11 253 views
0

我正在使用套接字C#。我已經使用套接字實現了一個客戶端服務器應用程序,但問題是客戶端沒有收到服務器發送的所有數據。客戶端服務器套接字C#

這是客戶端應用程序代碼。我該怎麼做才能收到服務器發送的所有數據?

strRecieved = ""; 
Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9001); 
soc.Connect(endPoint); 
byte[] msgBuffer = Encoding.Default.GetBytes(path); 
soc.Send(msgBuffer, 0, msgBuffer.Length, 0); 
byte[] buffer = new byte[2000]; 
int rec = soc.Receive(buffer); 

strRecieved = String.Format(Encoding.Default.GetString(buffer)); 
+0

所以,你已經創建了一個IP套接字發送給自己呢? ..你的例子中的路徑似乎未定義。路有多大?更準確地說,msgbuffer有多大?你的接收緩衝區有沒有機會獲得你告訴它的2000字節?和消息更大? – BugFinder

+0

準確地說,要接收的味精更大,我沒有收到整個味精,我應該如何設置可能收到的最大味精?謝謝 – user7394882

+0

那麼爲什麼你將緩衝區設置爲2000? – BugFinder

回答

1

首先。如果你正在實現某種流媒體功能(tcp/udp/file),你應該考慮使用某種協議

什麼是協議?這只是流數據時使用的一種方案。例如:

[4字節 - 長度] [lengthBytes的 - 消息] [1字節 - 終止指示器]

知道所述協議可以簡單地讀取所有的進入數據的字節爲這樣:

byte[] buffer = new byte[4]; 
stream.ReadBytes(buffer, 0, 4); // cast that to int and read the rest 

int packetLen = BitConverter.ToInt32(buffer, 0); 
buffer = new byte[packetLen]; 
stream.ReadBytes(buffer, 0, buffer.Length); // all bytes that was sent 

請記住,在發送消息之前,您必須在長度中減去4個字節。

編輯:關於如何發送和接收數據

簡單實例使用共享協議

// sender.cs 
string _stringToSend = "some fancy string"; 
byte[] encodedString = Encoding.UTF8.GetBytes(_stringToSend); 
List<byte> buffer = new List<byte>(); 
buffer.AddRange(BitConverter.GetBytes(encodedString.Length)); 
buffer.AddRange(encodedString); 
netStream.WriteBytes(buffer.ToArray(), 0, buffer.Count); 
// netStream sent message in protocol [@LEN - 4Bytes][@MSG - @LENBytes] 
// simply speaking something like: 5ABCDE 

// receiver.cs 
byte[] buffer = new byte[sizeof(int)]; 
netStream.ReadBytes(buffer, 0, buffer.Length); 
// receiver got the length of the message eg. 5 
int dataLen = BitConverter.ToInt32(buffer, 0); 
buffer = new byte[dataLen]; 
// now we can read an actual message because we know it's length 
netStream.ReadBytes(buffer, 0, buffer.Length); 
string receivedString = Encoding.UTF8.GetString(buffer); 
// received string is equal to "some fancy string" 

使其更簡單

這種技術力量您使用期望的協議,其在該示例將是:

前4個字節sizeof(int)正指示輸入分組 的長度每一個字節都是你的數據包,直到結束。

所以現在你應該ProtocolHelper對象:

public static class ProtocolHelper 
{ 
    public byte[] PackIntoProtocol(string message) 
    { 
     List<byte> result = new List<byte>(); 
     byte[] messageBuffer = Encoding.UTF8.GetBytes(message); 
     result.AddRange(BitConverter.GetBytes(messageBuffer.Length), 0); // this is the first part of the protocol (length of the message) 
     result.AddRange(messageBuffer); // this is actual message 
     return result.ToArray(); 
    } 

    public string UnpackProtocol(byte[] buffer) 
    { 
     return Encoding.UTF8.GetString(buffer, 0, buffer.Length); 
    } 
} 

現在(取決於您選擇從網絡讀取方法),你必須發送和接收消息。

// sender.cs 
string meMessage = "network message 1"; 
byte[] buffer = ProtocolHelper.PackIntoProtocol(meMessage); 
socket.Send(buffer, 0, buffer.Length, 0); 

// receiver.cs 
string message = string.Empty; 
byte[] buffer = new byte[sizeof(int)]; // or simply new byte[4]; 
int received = socket.Receive(buffer); 
if(received == sizeof(int)) 
{ 
    int packetLen = BitConverter.ToInt32(buffer);// size of our message 
    buffer = new byte[packetLen]; 
    received = socket.Receive(buffer); 
    if(packetLen == received) // we have full buffer 
    { 
     message = PacketHelper.UnpackProtocol(buffer); 
    } 
} 
Console.WriteLine(message); // output: "network message 1" 
+0

我正在使用tcp ip協議,只是檢查我放的源代碼, – user7394882

+0

什麼是變量netStream,我正在使用sokcet.rceive(buffer)如何更新我的代碼非常感謝 – user7394882

+0

@ m.rogaski在類協議幫助程序什麼是變量結果是什麼它的類型? – user7394882