TCP套接字recv()获取旧输入

时间:2019-06-28 08:19:47

标签: c sockets tcp

我正在尝试使用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的工作方式,但是在下次读取之前,有没有办法丢弃其余的额外数据?

1 个答案:

答案 0 :(得分:1)

数据以连续字节流的形式存储在套接字中。它没有用于不同数据的任何标识符。根据您的情况,可能有两种解决方法:

  1. 使用二进制同步协议。 (使用STX-文本开始和ETX-文本结束)来标识文本的开始和结束。

  2. 在数据开头附加要发送的数据字节数。套接字将读取前四个字节,并将获取要从套接字接收的字节数。然后读取所有数据并获取所需的数据量。

嗯...似乎很难... ??让我举一个例子。

实际数据需要发送: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。现在,您可以根据需要截断该值。