2016-08-04 48 views
0

Ich arbeite gerade an einem TCPClient und Server. In letzter Zeit habe ich eine Verschlüsselung für die Nachrichten hinzugefügt und hatte keine Probleme. Einmal begann ich zu bemerken, dass ich eine seltsame Fehler wie diese bekommen:C# TCPClient-Server sendet nicht immer die vollen Daten

Error

Aber es ist völlig zufällig, und keine Ahnung, warum. Es passiert bei größeren Nachrichten, aber wie gesagt, nicht immer.

Überprüfen der byte [] Länge auf der Server-Seite sagt, 1920 (Manchmal sagt es 1920 auf dem Client auch, und das ist der Punkt, wenn ich Fehler nicht haben)

Auf Client es viel weniger sagt.

Weird crap

Ich glaube tatsächlich, dass manchmal der Client nicht die vollständige Byte empfängt, dass es sollte, das ist, wie ich es tun:

Auftraggeber:

byte[] bb = new byte[12288]; 
int k = stm.Read(bb, 0, 12288); 
string message = Encoding.UTF8.GetString(bb, 0, k); 
MessageBox.Show(message.Length.ToString()); // This sometimes says 1460, and 1920 
message = Encrypter.DecryptData(message); // Error here If the length is not 1920 

Server:

bmsg = Encrypter.EncryptData(((int)Codes.XYZEnum) + "=" + data); 
Logger.Log(bmsg.Length.ToString()); // Original msg, always says 1920 
s.Send(asen.GetBytes(bmsg)); 
s.Close(); 

Was könnte das Problem sein? Sollte ich Async-Senden versuchen?

LÖSUNG:

Server-Code, hat mich ein wenig, während es cool zu machen:

System.Net.Sockets.Socket s = myList.AcceptSocket(); // Accept the connection 

Stream stream = new NetworkStream(s); // Create the stream object 
byte[] leng = new byte[4]; // We will put the length of the upcoming message in a 4 length array 
int k2 = s.Receive(leng); // Receive the upcoming message length 
if (BitConverter.IsLittleEndian) 
{ 
    Array.Reverse(leng); 
} 
int upcominglength = (BitConverter.ToInt32(leng, 0)); // Convert it to int 

byte[] b = ByteReader(upcominglength, stream); // Create the space for the bigger message, read all bytes until the received length! 

string message = Encoding.UTF8.GetString(b, 0, b.Length); // Convert it to string! 


internal byte[] ByteReader(int length, Stream stream) 
{ 
    byte[] data = new byte[length]; 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     int numBytesRead; 
     int numBytesReadsofar = 0; 
     while (true) 
     { 
      numBytesRead = stream.Read(data, 0, data.Length); 
      numBytesReadsofar += numBytesRead; 
      ms.Write(data, 0, numBytesRead); 
      if (numBytesReadsofar == length) 
      { 
       break; 
      } 
     } 
     return ms.ToArray(); 
    } 
} 

Client-Code, und es funktioniert gut !:

var result = tcpclnt.BeginConnect(User.IP, User.Port, null, null); 
var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(3)); // Connect with timeout 

if (!success) 
{ 
    return "Failed to connect!"; 
} 
Stream stm = tcpclnt.GetStream(); // get the stream 

UTF8Encoding asen = new UTF8Encoding(); 

byte[] ba = asen.GetBytes(msg); // get the bytes of the message we are sending 
byte[] intBytes = BitConverter.GetBytes(ba.Length); // Get the length of that in bytes 
if (BitConverter.IsLittleEndian) 
{ 
    Array.Reverse(intBytes); 
} 

stm.Write(intBytes, 0, intBytes.Length); // Write the length in the stream! 
stm.Flush(); // Clear the buffer! 
stm.Write(ba, 0, ba.Length); // Write the message we are sending! 

// If we have answers.... 
byte[] bb = new byte[10000]; 
int k = stm.Read(bb, 0, 10000); 
string mmessage = Encoding.UTF8.GetString(bb, 0, k); 
// If we have answers.... 


tcpclnt.Close(); // Close the socket 

Antwort

2

Weil nur 8Kb können durch einmal Paket senden. Wenn Sie große Datenmengen haben, müssen Sie den Zyklus verwenden.

+0

Würde async senden das lösen? – DreTaX

+0

Nein, ich denke nur Sync und ein separater Thread – Adil