本文主要是介绍关于recv的一点困惑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
我用setsockopt()设置TCP_NODELAY后,让客户端连续发送10次数据,每次为1个字节。怎么才能使服务端每次都收到1个字节,而不是一次收到10个字节,就是用recv收到1个字节?尝试用select()函数,或者是WSAAsyncSelect(),都会一次收到9个或10个字节,难道客户端发送的速度很快的话,几次发送的数据都存到了服务端的缓冲区里,连这两个函数也不能准确检查出有新数据来了吗?其实我的目的就是有没有办法准确判断出服务端接收了一个字节?接到到一个字节就通知有东西来了。问题可能不清楚,我也是个菜鸟。请大侠指教。 -------------------------------------------------------------------------------- 答:使用recv(fd,buff,1,0) -------------------------------------------------------------------------------- 答:ls正解 -------------------------------------------------------------------------------- 答:首先,你一次性把10个字节数据收了和一次一次收1个字节数据有区别嘛?不会你要用TCP做定时吧。如果你一定要一次收一个字节,那剩下的也是放在接收缓冲里不取而已。 -------------------------------------------------------------------------------- 答:是这样的,你的程序里可以用一个变量作缓冲区,但是你的机器内部还有一个缓冲区,机器内部的缓冲区实际上是由tcp协议控制的,你不能操作它,实际上你的程序是用变量缓冲区从你的机器缓冲区读东西。 -------------------------------------------------------------------------------- 答:使用recv(fd,buff,1,0)应该没问题,可以达到我提问中的效果。但我的本意是如果不知道对方发的是几个字节,我还是想判断出对方每个包发的是什么?比如对方按顺序发1个,2个,3个,2个,那我就不能用recv(fd,buff,1,0)。那怎么解决了? -------------------------------------------------------------------------------- 答:客户端连续发送10次数据也不一定真发了10个数据包,客户端发送数据也是有缓存的,也许只发了1次10字节的数据包. -------------------------------------------------------------------------------- 答:TCP方式是流式传输,应该不太可能判断出对方每个发包有一种方法就是自己定义发送包的格式,比如说发送端的buf格式为:一字节或多字节标志(可以自己定)一字节发送数据长度数据接收端在收的时候,判断接收数据的标志字节的位置,找到标志位后,那么后面一个字节就是发送端发送数据的长度,以此解决问题 -------------------------------------------------------------------------------- 答:设置缓冲区大小为1个字节 -------------------------------------------------------------------------------- 答:bluepuzzle说的有道理! -------------------------------------------------------------------------------- 答:recv10次每次接收1个字节的buf就可以了..不知道你的用意 -------------------------------------------------------------------------------- 答:LZ的问题是,他不关心发送端是怎么发的,他只关心接收的时候,是按发送的情况一样(recv和send次数一样,每次recv到的数据内容,大小和每次send的数据内容,大小一样)看看这个?!http://support.microsoft.com/kb/214397/zh-cn是需要双方都设置TCP_NODELAY??? -------------------------------------------------------------------------------- 答:设置了TCP_NODELAY好像是发送时分开但是并不能保证接收的时候也能分开收正如bluepuzzle所说可以自己实现包结构 -------------------------------------------------------------------------------- 答:经过实际测试,设置了TCP_NODELAY为true,SO_SNDBUF与SO_RCVBUF为0都无法实现 -------------------------------------------------------------------------------- 答:感谢jourbin的测试,我的实际意图正如jourbin所说,看来这个问题在这个层面上无法解决,只能自己设置包结构,或者协议等了。比如先收一个几字节的数据长度,再来接收该长度的数据。 -------------------------------------------------------------------------------- 答:传统的做法是一定要定义一个包格式的,这个包头结构中必须有消息的总长度,这样在接受时,先接受头几个字节固定字节,这个固定的字节表示该包长度,然后再按长度接受即可。恰好我前段时间写过这段代码,贴上来参考一二吧。voidCMySocket::OnReceive(intnErrorCode){intiRet;intiReadLen=0;//charLength[4];char*pBuf=NULL;//第一次读固定长度的字节,这个固定长度的字节表示为包长度while(iReadLen<4){iRet=Receive(LengthiReadLen,4-iReadLen);if(iRet==0)return;if(iRet==SOCKET_ERROR){return;}iReadLen=iRet;}intiLen;memcpy(&iLen,Length,4);iLen=ntohl(iLen);//按接受包长度创建buf长度pBuf=newchar[iLen];memcpy(pBuf,Length,4);//包体部分接收while(iReadLen这篇关于关于recv的一点困惑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!