免责声明:我对此非常陌生,所以我会尽可能地清楚。
我有一个变量"数据包"数据大小。我知道TCP是一种流媒体协议 - 它会传输字节,而不是数据包。
现在,我想告诉我的客户从流中读取的数据大小(构成我的一个数据包')。
我发送的数据是std::string
格式
如果我的字符串被称为outstring
,我怎么能用我需要在客户端读取的字符串大小填充UINT8 buff[4]
?
我的客户端,用C#编写,看起来像这样:
int total = 0;
int read;
byte[] datasize = new byte[4];
read = socket.Receive(datasize, 0, 4, 0);
int size = BitConverter.ToInt32(datasize, 0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size) {
read = socket.Receive(data, total, dataleft, 0);
if (read == 0) {
break;
}
total += read;
dataleft -= read;
}
答案 0 :(得分:3)
道歉,这不是您问题的直接答案,但可能有用。
使用原始套接字进行编程很糟糕。要使程序能够有效地处理它们,还有很多工作要做。例如,在您的代码段中,您尝试将4个字节接收到datasize中。无法保证单个socket.Receive()操作实际上会读取4个字节,它可以读取1到4个字节之间的任何内容。你必须在循环中调用socket.Receive(),直到你收到所有4个字节,就像你以后一样。
幸运的是,像ZeroMQ之类的东西几乎消除了所有的痛苦,并为你提供了一个很好的简单消息传递框架,分布在套接字,管道,内存等之上。如果你只是想得到一些事情,强烈建议。
答案 1 :(得分:1)
byte[0] = l & 0x000000ff;
byte[1] = (l & 0x0000ff00) >> 8;
byte[2] = (l & 0x00ff0000) >> 16;
byte[3] = (l & 0xff000000) >> 24;
这假设你想要它以小端格式。如果你想要bigendian
byte[3] = l & 0x000000ff;
byte[2] = (l & 0x0000ff00) >> 8;
byte[1] = (l & 0x00ff0000) >> 16;
byte[0] = (l & 0xff000000) >> 24;
答案 2 :(得分:0)
您的发送代码是用C ++编写的,所以您根本不需要字节数组,可以直接发送整数大小值,例如:
uint32_t size = htonl(outstring.size()); // convert from host byte order to network byte order (big endian)
send(theSocket, (char*)&size, sizeof(size), 0);
send(theSocket, outstring.c_str(), outstring.size(), 0);
在.NET客户端,您可以执行以下操作:
bool readSocketFully(Socket s, byte[] buf)
{
int idx = 0;
int dataleft = buf.Length;
int read;
while (dataleft > 0) {
read = s.Receive(buf, idx, dataleft, 0);
if (read == 0) {
return false;
}
idx += read;
dataleft -= read;
}
return true;
}
byte[] readPacket(Socket s)
{
byte[] datasize = new byte[4];
if (!readSocketFully(s, datasize)) {
return null;
}
if (BitConverter.IsLittleEndian) {
System.Array.Reverse(datasize, 0, 4); // convert from network byte order (big endian) to host byte order (little endian)
}
int size = BitConverter.ToInt32(datasize, 0);
byte[] data = new byte[size];
if (size > 0) {
if (!readSocketFully(socket, data)) {
return null;
}
}
return data;
}
byte[] data = readPacket(socket);
// use data as needed ...