昨天遇到一个问题,我使用客户端来接收一个服务器发送的消息进行判断,然后再转发给另一个服务器。在这个过程中需要随时清空已经接收过的服务器数据,但是使用memset只能在recv接收完毕清空,而无法随时清空,
尝试了很多修改代码逻辑的方法来解决问题,但都不行,后来才发现必须要能够随时清空接受到的buf才能解决问题。
因为时间紧迫,没有想到太好的办法,就临时加了一个线程,一个线程用来接收数据,将接收到不合适的数据memset,合适的数据传给另一个线程执行。
这个线程用来判断数据,如果数据不合适就清除。
while (readLen = recv(hSocket, message, 1, 0))
{
if (readLen == -1)
ErrorHandling("读取失败");
printf("%s\n", message);
if (&message == '0')
{
}
else if(message[0] == '1')
{
}
memset(message, 0, strlen(message));
}
另一个线程用来检测数据接收情况,发送给另外一个服务器。
这样是把问题解决了,但是还是没有搞清楚recv()接收的原理,经过多次测试才发现,memset清空的只是recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags)中buf的缓存。
查阅资料得知:缓冲区有两种。第一种是用户定义的缓冲区,就是recv里的缓冲区参数。另一种就是套接字缓冲区,是由协议自定的。可以用getsockopt获取其大小,并用setsockopt重置其大小。发送的时候使用send实际上是从用户缓冲区发送到socket缓冲区中,至于数据真正何时发送给另一端则是由协议规定的。Recv也类似。
所以每次清空都是无效的。只能读出之后再处理。