简体   繁体   English

C#TCPClient-Server并不总是发送完整数据

[英]C# TCPClient-Server doesn't always send the full data

I'm currently working on a TCPClient and Server. 我目前正在使用TCPClient和Server。 Lately I added an encryption for the messages, and had no trouble. 最近,我为消息添加了加密,并且没有问题。 Once I started noticing that I'm getting a weird error like this: 一旦我开始注意到我收到了一个奇怪的错误,如下所示:

错误

But It's totally random, and no idea why. 但这是完全随机的,不知道为什么。 It happens at larger messages, but as I said, not always. 它发生在较大的消息中,但正如我所说,并非总是如此。

Checking the byte[] length at the server side says 1920 (Sometimes it says 1920 on the client too, and thats the point when i dont have error) 在服务器端检查byte []长度说1920(有时在客户机上也说1920,这就是我没有错误的关键)

On client it says a lot lesser. 在客户看来,它要少得多。

奇怪的废话

I actually think that sometimes the client doesn't receive the full byte that It should, this is how I do It: 我实际上认为有时客户端没有收到应有的完整字节,这就是我的做法:

Client: 客户:

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

What could be the problem? 可能是什么问题呢? Should I try async sending? 我应该尝试异步发送吗?

SOLUTION: 解:

Server code, took me a little while to make it cool: 服务器代码,花了我一些时间使其变得很酷:

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, and it is working nicely!: 客户端代码,并且运行良好!:

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

Because only 8Kb can to send by once packet. 因为只有8Kb可以一次发送一个数据包。 if you have large data you need use cycle. 如果您有大量数据,则需要使用周期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM