[英]C# reading wrong data from socket
I'm trying to send a random words over one socket to another. 我正在尝试通过一个套接字向另一个套接字发送随机单词。 I designed a simple protocol for the data management, every data package contains in it's first 4 bytes the length of the actual message(as bytes,),then the message itself. 我为数据管理设计了一个简单的协议,每个数据包的前4个字节中包含实际消息的长度(以字节为单位),然后是消息本身。
This is the client code: 这是客户端代码:
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();
}
As you see, i generate a random word,write it's first 4 bytes(simply shift the bits) and then copying it to the sendBuffer. 如您所见,我生成一个随机字,将其写入前4个字节(只需将位移位),然后将其复制到sendBuffer。
Server code: 服务器代码:
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();
}
In the server side,i read the first 4 bytes to get the length(so i can know how much do i have to read),then i start looping until the end of the data size. 在服务器端,我读取前4个字节以获取长度(这样我就知道必须读取多少字节),然后我开始循环直到数据大小结束。
I actualy dont know how to explain this, it works for 2 or 3 seconds ,then the Server
throws a System.ArgumentOutOfRangeException
expection in this line: 我实际上不知道如何解释它, 它可以工作2或3秒钟 ,然后Server
在此行中抛出System.ArgumentOutOfRangeException
期望:
recv = rSocket.Receive(recieveBuffer, totalread, dataleft, 0); recv = rSocket.Receive(recieveBuffer,totalread,dataleft,0);
I debugged this and found the size
variable holds very large numbers...(few millions for example),so i guess the problem is by reading the first 4 bytes... 我调试了它,发现size
变量包含非常大的数字...(例如几百万),所以我想问题出在读取前4个字节...
I also tried to output the first 4 values of the recieveBuffer
and they were different from the values in the client side..(when the exception throwed,by then they were the same). 我还尝试输出recieveBuffer
的前4个值,它们与客户端中的值不同。(抛出异常时,它们是相同的)。
I'm not sure what's wrong here.. i'll appreciate every help. 我不确定这是怎么回事..我将感谢您的帮助。
Thanks. 谢谢。
… there's an error in your calculation: when you compare totalread < size , size doesn't include the 4 bytes for the length of the message, but you already added them to totalread, so you should either start totalread from 0 ignoring the 4 bytes of the length, or your writing code should add them to the total length. …您的计算中存在错误:比较totalread <size时,size不包括消息长度的4个字节,但是您已经将它们添加到totalread中,因此您应该从0开始忽略totalread而不考虑4个字节长度,否则您的编写代码应将它们加到总长度中。 – o_weisman – o_weisman
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.