2016-08-04 2 views
0

В настоящее время я работаю над TCPClient и сервером. В последнее время я добавил шифрование для сообщений и не имел никаких проблем. После того, как я начал замечать, что я получаю странные ошибки, как это:C# TCPClient-Server не всегда отправляет полные данные

Error

Но это совершенно случайно, и не знаю, почему. Это происходит при больших сообщениях, но, как я уже сказал, не всегда.

Проверка байт [] длину на стороне сервера говорит 1920 (Иногда он говорит 1920 на клиенте тоже, и вот в момент, когда я не имею ошибку)

На клиенте он говорит много меньше.

Weird crap

Я на самом деле думаю, что иногда клиент не получает полный байт, что он должен, это, как я это сделать:

Клиент:

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 

Сервер:

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

В чем может быть проблема? Должен ли я попробовать асинхронную отправку?

РЕШЕНИЕ:

код сервера, мне потребовалось некоторое время, чтобы сделать это круто:

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(); 
    } 
} 

код клиента, и он работает хорошо !:

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 

ответ

2

Поскольку только 8Kb может отправить один раз пакет. если у вас большие данные, вам нужен цикл использования.

+0

Будет ли асинхронная отправка решения этой? – DreTaX

+0

Нет, я думаю, что только синхронизация и отдельная тема – Adil