一个关于UDP socket服务端接收长度不正确的问题
2014-11-01 21:10
447 查看
最近项目需要实现一个通过UDP协议和远端服务平台通讯的需求,简要描述如下:
本端为嵌入式linux路由器(udp客户端,linux C编码),远端为租用的阿里云服务器(udp服务端,java编码),
通信协议为UDP,本端会定时向远端服务器发送消息。
在实现和调试过程中发现一个问题:
1)将远端服务程序放在实验室pc机上调试没有问题,即“路由器-PC”交互正常。
2)将远端服务程序放至阿里云服务器上运行,结果服务端收到的udp消息会多出4个字节,偶尔还会多出6个,多出的字节是 EF BF 之类的。
3)在远端服务器通过tcpdump抓包发现,tcpdump抓到的udp报文长度是正确的,并没有多出4个字节。
4)在检查并尝试字节序、字节对齐等问题后,仍然没有找到问题的原因。
5)最后,想到把消息中传输数值的地方,全部转换为字符串方式传输,结果问题没了,但是原因还无法确定。
6)在网上搜到一篇类似问题的帖子,但是,没有给出最终解决方案,链接如下:
http://bbs.csdn.net/topics/370180910
1. 发现问题的代码实现,即消息传输中有数值
关键数据结构定义为:
另外,为了彻底排除字节对齐的影响,还尝试了单个字节逐一赋值的方式,即
2. 将消息中的数值全部转换为字符串方式传输,服务器端接收正常
还请各位大虾帮忙看看有没有遇到过类似的问题,或者帮忙指出该问题的原因到底在哪?
本端为嵌入式linux路由器(udp客户端,linux C编码),远端为租用的阿里云服务器(udp服务端,java编码),
通信协议为UDP,本端会定时向远端服务器发送消息。
在实现和调试过程中发现一个问题:
1)将远端服务程序放在实验室pc机上调试没有问题,即“路由器-PC”交互正常。
2)将远端服务程序放至阿里云服务器上运行,结果服务端收到的udp消息会多出4个字节,偶尔还会多出6个,多出的字节是 EF BF 之类的。
3)在远端服务器通过tcpdump抓包发现,tcpdump抓到的udp报文长度是正确的,并没有多出4个字节。
4)在检查并尝试字节序、字节对齐等问题后,仍然没有找到问题的原因。
5)最后,想到把消息中传输数值的地方,全部转换为字符串方式传输,结果问题没了,但是原因还无法确定。
6)在网上搜到一篇类似问题的帖子,但是,没有给出最终解决方案,链接如下:
http://bbs.csdn.net/topics/370180910
1. 发现问题的代码实现,即消息传输中有数值
unsigned char tmpBuf[DIAG_NOTIFY_LEN] = {0}; unsigned short usCrc = 0, uslen = 0; memset(tmpBuf, 0, DIAG_NOTIFY_LEN); ((NotifyHeader *)(tmpBuf))->HeaderFlag = htons(DIAG_MSG_HEADER); ((NotifyHeader *)(tmpBuf))->MsgType = htons(DIAG_NOTIFY_MSG); ((NotifyHeader *)(tmpBuf))->SeqNum = htons(g_usLastSeq); ((NotifyHeader *)(tmpBuf))->DataLen = htons(strlen(macBuf)); sprintf(tmpBuf+sizeof(NotifyHeader), "%s", macBuf); uslen = sizeof(NotifyHeader) + strlen(macBuf); usCrc = CRC16(tmpBuf, uslen); *(tmpBuf+uslen) = (usCrc & 0xff00) >> 8; *(tmpBuf+uslen+1) = usCrc & 0x00ff; if(0 > sendto(g_diagSockFd, tmpBuf, uslen+DIAG_CRC_LEN, 0, g_pstAddrInfo->ai_addr, g_pstAddrInfo->ai_addrlen)) { perror("diag_notify [sendto]"); }
关键数据结构定义为:
typedef struct tagNotifyHeader { unsigned short HeaderFlag; unsigned short MsgType; unsigned short SeqNum; unsigned short DataLen; }NotifyHeader;考虑到字节对齐问题,定义时特意注意了一下保证数据结构的字节对齐。
另外,为了彻底排除字节对齐的影响,还尝试了单个字节逐一赋值的方式,即
*tmpBuf = (DIAG_MSG_HEADER & 0xFF00) >> 8; *(tmpBuf+1) = DIAG_MSG_HEADER & 0x00FF; ......结果问题依旧存在,后来想到全部转换为字符串的方式传输(如下),结果服务器端接收ok。
2. 将消息中的数值全部转换为字符串方式传输,服务器端接收正常
unsigned char tmpBuf[DIAG_NOTIFY_LEN] = {0}; unsigned short usCrc = 0, uslen = 0; memset(tmpBuf, 0, DIAG_NOTIFY_LEN); uslen = sprintf(tmpBuf, "%x", DIAG_MSG_HEADER); uslen += sprintf(tmpBuf+uslen, "%x", DIAG_NOTIFY_MSG); uslen += sprintf(tmpBuf+uslen, "%4x", g_usLastSeq); uslen += sprintf(tmpBuf+uslen, "%4x", strlen(macBuf)); uslen += sprintf(tmpBuf+uslen, "%s", macBuf); usCrc = CRC16(tmpBuf, uslen); uslen += sprintf(tmpBuf+uslen, "%4x", usCrc); if(0 > sendto(g_diagSockFd, tmpBuf, uslen, 0, g_pstAddrInfo->ai_addr, g_pstAddrInfo->ai_addrlen)) { perror("diag_notify [sendto]"); }结果问题虽然不出现了,但是原因没有找到,目前怀疑会不会与字符集有关。
还请各位大虾帮忙看看有没有遇到过类似的问题,或者帮忙指出该问题的原因到底在哪?
相关文章推荐
- 关于udp socket recvfrom函数的一个易错问题: 如果应用程序指定的接收长度不够怎么办?
- 同一个Socket实例第二次无法接收服务端数据!! (暂时占用一下首页,请多包涵,该问题困扰我两天了)
- 关于SOCKET编程里面udp编程sendto和recvfrom的问题
- SOS-关于Socket类接收的问题
- 参数读取一个关于java.net.Socket的超时的问题
- 安卓使用Socket发送中文,C语言服务端接收乱码问题解决方案
- Socket编程 关于缓冲区长度问题
- 关于进入windows界面时,提示了:一个问题阻止windows正确检查此机器许可证,错误代码为:
- 新问题:一个进程最多可以接收多少个socket连接? - C/C++ - ChinaUnix.net -
- 关于UDP向本机端口发送数据报但是接收不到数据的问题
- 一个socket连接、发送、接收数据失败后是否可以重新进行连接的问题
- flex与socket通信之成功----之成功补充篇(关于C#建立FLASH服务端的安全沙箱问题)
- JAVA SOCKET服务端接收C客户端字节长度的问题
- 关于scanf()不能正确接收有空格符的字符串的问题
- 关于socket的接收堵塞问题
- 关于《一个SQL语句查询问题(查询最小值)(急)》回复里面没有正确理想的答案!
- 关于数据库长度限制和.NET中处理正确长度等问题
- 一个关于java.net.Socket的超时的问题
- 关于socket网络的一个小问题
- 关于socket编程的一个常坑问题,readLine()