我是Socket编程的新手。我正在尝试创建一个客户端应用程序。该服务器是使用TCP进行通信的摄像机。相机正在发送连续数据。使用Wireshark,我可以看到相机正在发送连续大小不同但不超过1514字节的数据包。但是我的recv
函数总是返回2000
,这就是缓冲区的大小。
unsigned char buf[2000];
int bytesIn = recv(sock, (char*)buf, sizeof(buf) , 0);
if (bytesIn > 0)
{
std::cout << bytesIn << std::endl;
}
我收到的第一个数据包的大小为9
个字节,recv
返回正确,但此后总是返回2000。
有人可以告诉我解决方案,以便我可以获取实际数据有效负载的正确大小吗?
编辑
int bytesIn = recv(sock, (char*)buf, sizeof(buf) , 0);
if (bytesIn > 0)
{
while (bytes != 1514)
{
if (count == 221184)
{
break;
}
buffer[count++] = buf[bytes++];
}
std::cout << count;
}
编辑:
这是我对Wireshark的捕获:
我的代码以处理数据包
int bytesIn = recv(sock, (char*)&buf, sizeof(buf) , 0);
if (bytesIn > 0)
{
if (flag1 == true)
{
while ((bytes != 1460 && (buf[bytes] != 0)) && _fillFlag)
{
buffer[fill++] = buf[bytes++];
if (fill == 221184)
{
flag1 = false;
_fillFlag = false;
fill = 0;
queue.Enqueue(buffer, sizeof(buffer));
break;
}
}
}
if ((strncmp(buf, _string2, 10) == 0))
{
flag1 = true;
}
}
对于每个帧,相机发送221184字节,并且在每个帧之后发送一个9字节的数据包,我用来比较这9个字节是恒定的。
相机发送的这221184个字节没有0,因此我在while循环中使用此条件。这段代码可以正常工作并显示框架,但几帧后显示全黑框架。我认为错误在于接收数据包。
答案 0 :(得分:1)
我收到的第一个数据包的大小为9字节,此数据包打印正确后便始终打印2000。所以任何人都可以告诉我我只得到实际数据有效负载大小的解决方案。
TCP不是面向分组的,而是面向流的传输协议。 TCP中没有数据包的概念(可能还包括MTU)。如果要使用数据包,则必须使用UDP(实际上是面向数据包的,但默认情况下在顺序,丢弃等方面并不可靠),或者必须在TCP中实现数据包逻辑,即从a收到数据后,将数据流化并划分为逻辑数据包。
答案 1 :(得分:1)
Size of per frame is : 221184 (fixed)
Size of per recv is : 0 ~ 1514
我的实现此处:
DWORD MakeFrame(int socket)
{
INT nFrameSize = 221184;
INT nSizeToRecv = 221184;
INT nRecvSize = 2000;
INT nReceived = 0;
INT nTotalReceived = 0;
BYTE byCamera[2000] = { 0 }; // byCamera size = nRecvSize
BYTE byFrame[221184] = { 0 }; // byFrame size = nFrameSize
while(0 != nSizeToRecv)
{
nRecvSize = min(2000, nSizeToRecv);
nReceived = recv(socket, (char*)byCamera, nRecvSize, 0);
memcpy_s(byFrame + nTotalReceived, nFrameSize, byCamera, nReceived);
nSizeToRecv -= nReceived;
nTotalReceived += nReceived;
}
// byFrame is ready to use.
// ...
// ...
return WSAGetLastError();
}