我正在尝试使用Winsock通过TCP从客户端接收多个值。我的recv()调用占用1 KB的数据,但是如果客户端发送的数据更多,则在下一个recv()调用期间将收到该数据。
我尝试使用循环来检查接收到的数据何时变为0,但这只是使程序挂起。
这是我的recv()调用:
int iResult = recv(ClientSocket, recvbuf, 1024, 0);
recvbuf的长度为1024字节。客户端使用netcat连接到服务器。这是一个示例方案:
# nc 10.10.10.10 1111
Enter username: < "A" * 2048 >
Enter password: "password"
在Visual Studio中调试时,我看到在第一次调用recv()之后,recvbuf包含“ A” * 1024,但是当我再次使用recv()存储密码时,我收到了剩余的1024 A,而不是“密码”。
我认为这是TCP的工作方式,但是在下次读取之前,有没有办法丢弃其余的额外数据?
答案 0 :(得分:1)
数据以连续字节流的形式存储在套接字中。它没有用于不同数据的任何标识符。根据您的情况,可能有两种解决方法:
使用二进制同步协议。 (使用STX-文本开始和ETX-文本结束)来标识文本的开始和结束。
在数据开头附加要发送的数据字节数。套接字将读取前四个字节,并将获取要从套接字接收的字节数。然后读取所有数据并获取所需的数据量。
嗯...似乎很难... ??让我举一个例子。
实际数据需要发送:ABCDEFGHIJ
新数据格式:0010ABCDEFGHIJ
服务器端所需的数据:ABCDE
recv函数将读取前4个字节以获取实际数据的字节数:
int iResult = recv(ClientSocket, recvbuf, 4, 0);
根据上述情况,“ recvbuf”将被0010转换为整数,将给出值“ 10”,该值可以存储在某些整数变量中。所以我们有:
int toReadVal = 10
现在我们需要的是在下一个recv调用中读取这10位数字:
int iResult = recv(ClientSocket, recvbuf1, toReadVal, 0);
最后,我们将recvbuf1的值为ABCDEFGHIG。现在,您可以根据需要截断该值。