基于UDP协议的recvfrom函数无法获取一个完整的UDP包,该如何解决
基于UDP协议的recvfrom函数无法获取一个完整的UDP包
利用这个函数接收对端的数据,首先等待对端响应,响应函数中主要是利用select等待套接字是否可读,如下
并且由于接收操作是放在一个单独的线程里的,所以使用的是阻塞模式等待数据到达,一旦数据到了,那么我就开始接收
RecvDataFromPeer();这个函数中封装了recvfrom函数,然后将收到的数据放到本地缓冲区中
现在的问题是:每次调用RecvDataFromPeer();也即recvfrom,用抓包工具看完整的一个UDP数据包如下
但是每次从recvfrom返回时我只能接收到80 C8这2个字节。
所以有没有这样一种可能,当前协议栈正在接收一个UDP数据包的时候,还没全部收完,然后进程切换,由于本地使用同步模式阻塞在这个套接字上,select检测到当前套接字上数据可读,然后直接返回,再调用recvfrom返回了整个包的一部分?
PS:对端服务器发送的是一个几十M的文件,每次切成一个块,然后使用UDP不停地发。
------解决方案--------------------
我是真心不懂为啥都喜欢用字符串保存二进制数据
要说新手图简单吧,也有不少写这种代码的人水平比我更好
要说高手用得好吧,为啥又犯一些低级错误呢
std::string(rBuffer)
std::string是字符串容器,其构造函数按C风格字符串解释输入指针指向的内存,最终调用的是strlen函数
你收到的数据包第三个字节就是0,它当然只解析前两个字节
------解决方案--------------------
buf不一定是字符串, 不能直接std::string(buf),试试std::vector<char>
------解决方案--------------------
你得把recvfrom的返回值也带上,这才是真正到的接收数据的长度
void RZAgent::RecvPeerData(WAIT_MODE _eWaitMode /* = ENUM_SYN */)
{
pNetConn->WaitForPeerResponse(_eWaitMode);
pNetConn->RecvDataFromPeer();
}
利用这个函数接收对端的数据,首先等待对端响应,响应函数中主要是利用select等待套接字是否可读,如下
::select(maxFd+1, &readySet, NULL, NULL, ptv)
并且由于接收操作是放在一个单独的线程里的,所以使用的是阻塞模式等待数据到达,一旦数据到了,那么我就开始接收
RecvDataFromPeer();这个函数中封装了recvfrom函数,然后将收到的数据放到本地缓冲区中
现在的问题是:每次调用RecvDataFromPeer();也即recvfrom,用抓包工具看完整的一个UDP数据包如下
80 C8 00 06 40 A5 8C 19 D7 5E 18 68 52 2D 0E 56 ....@... .^.hR-.V
6A 9F AA 5F 00 00 00 01 00 00 00 26 81 CA 00 06 j.._.... ...&....
40 A5 8C 19 01 0E 51 54 53 53 31 34 30 34 32 37 @.....QT SS140427
39 32 37 32 00 00 00 00 81 CC 00 06 40 A5 8C 19 9272.... ....@...
71 74 73 69 00 00 00 00 00 00 00 02 61 74 00 04 qtsi.... ....at..
00 00 00 14
但是每次从recvfrom返回时我只能接收到80 C8这2个字节。
所以有没有这样一种可能,当前协议栈正在接收一个UDP数据包的时候,还没全部收完,然后进程切换,由于本地使用同步模式阻塞在这个套接字上,select检测到当前套接字上数据可读,然后直接返回,再调用recvfrom返回了整个包的一部分?
PS:对端服务器发送的是一个几十M的文件,每次切成一个块,然后使用UDP不停地发。
------解决方案--------------------
我是真心不懂为啥都喜欢用字符串保存二进制数据
要说新手图简单吧,也有不少写这种代码的人水平比我更好
要说高手用得好吧,为啥又犯一些低级错误呢
std::string(rBuffer)
std::string是字符串容器,其构造函数按C风格字符串解释输入指针指向的内存,最终调用的是strlen函数
你收到的数据包第三个字节就是0,它当然只解析前两个字节
------解决方案--------------------
buf不一定是字符串, 不能直接std::string(buf),试试std::vector<char>
------解决方案--------------------
你得把recvfrom的返回值也带上,这才是真正到的接收数据的长度