[英]C# reading wrong data from socket
我正在尝试通过一个套接字向另一个套接字发送随机单词。 我为数据管理设计了一个简单的协议,每个数据包的前4个字节中包含实际消息的长度(以字节为单位),然后是消息本身。
这是客户端代码:
private byte[] sendBuffer = new byte[1000];
private Socket sSocket;
private void WriteDataLength(int length)
{
sendBuffer[0] = (byte)(length);
sendBuffer[1] = (byte)(length >> 8);
sendBuffer[2] = (byte)(length >> 16);
sendBuffer[3] = (byte)(length >> 24);
}
private void DoWork()
{
while (true)
{
string word = RandomString(random.Next(1, 10)); //generates a random string.
byte[] toBytes = Encoding.ASCII.GetBytes(word); //converting the string to byte array.
int length = toBytes.Length; // length of the actual data(the word length).
WriteDataLength(length);//writing the word length in bytes.
Buffer.BlockCopy(toBytes, 0, sendBuffer, 4, toBytes.Length);//copying the array which hold the word to the sendBuffer (start from the 4th byte).
sSocket.Send(sendBuffer, length+4 , SocketFlags.None);//send +4 bytes for the length prefix.
}
}
private static Random random = new Random();
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
private void Form1_Load(object sender, EventArgs e)
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("localhost", 10);
sSocket = tcpClient.Client;
Thread th = new Thread(DoWork);
th.Start();
}
如您所见,我生成一个随机字,将其写入前4个字节(只需将位移位),然后将其复制到sendBuffer。
服务器代码:
private byte[] recieveBuffer = new byte[1000];
TcpListener tListener;
Socket rSocket;
private int readData()
{
rSocket.Receive(recieveBuffer, 0, 4, SocketFlags.None); //read the first 4 bytes
int size = getDatalength(); //reassemble the bytes to the original value.
int dataleft = size;
int totalread = 4; //read already 4 bytes.
int recv;
while (totalread < size)
{
recv = rSocket.Receive(recieveBuffer, totalread, dataleft, 0);
if (recv == 0) //stop reading
{
break;
}
totalread += recv;
dataleft -= recv;
}
return size;
}
private int getDatalength()
{
int length = recieveBuffer[0] | recieveBuffer[1] << 8 | recieveBuffer[2] << 16 | recieveBuffer[3] << 24;
return length;
}
private void DoWork()
{
while (true)
{
int length = readData();
byte[] word = new byte[length]; //initializing a new array to hold the word
Buffer.BlockCopy(recieveBuffer, 4, word, 0, length); //copying to the recieveBuffer from the 4th place( first 4 bytes are always length header).
string result = Encoding.ASCII.GetString(word);
Console.WriteLine(result);
}
}
private void Form1_Load(object sender, EventArgs e)
{
tListener = new TcpListener(IPAddress.Any, 10);
tListener.Start();
rSocket = tListener.AcceptTcpClient().Client;
Thread th = new Thread(DoWork);
th.Start();
}
在服务器端,我读取前4个字节以获取长度(这样我就知道必须读取多少字节),然后我开始循环直到数据大小结束。
我实际上不知道如何解释它, 它可以工作2或3秒钟 ,然后Server
在此行中抛出System.ArgumentOutOfRangeException
期望:
recv = rSocket.Receive(recieveBuffer,totalread,dataleft,0);
我调试了它,发现size
变量包含非常大的数字...(例如几百万),所以我想问题出在读取前4个字节...
我还尝试输出recieveBuffer
的前4个值,它们与客户端中的值不同。(抛出异常时,它们是相同的)。
我不确定这是怎么回事..我将感谢您的帮助。
谢谢。
…您的计算中存在错误:比较totalread <size时,size不包括消息长度的4个字节,但是您已经将它们添加到totalread中,因此您应该从0开始忽略totalread而不考虑4个字节长度,否则您的编写代码应将它们加到总长度中。 – o_weisman
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.