社区
C语言
帖子详情
SOCKET收包总是会收到少量错误的消息
wb16860
2008-04-28 03:00:42
问题是这样的,在服务器端,从客户端收1种消息(消息长度,内容完全一样),先收固定长度的消息头,然后根据消息头中消息长度收消息体,再根据消息头中的消息类型进行处理.总是会出现1,2个消息类型错误的包.打印消息看了看,发现在消息内容被改写了.WIN32下以及LINUX下都测试过,都出现过这种问题,不知道是什么原因?
...全文
359
14
打赏
收藏
SOCKET收包总是会收到少量错误的消息
问题是这样的,在服务器端,从客户端收1种消息(消息长度,内容完全一样),先收固定长度的消息头,然后根据消息头中消息长度收消息体,再根据消息头中的消息类型进行处理.总是会出现1,2个消息类型错误的包.打印消息看了看,发现在消息内容被改写了.WIN32下以及LINUX下都测试过,都出现过这种问题,不知道是什么原因?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
14 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
wb16860
2008-04-28
打赏
举报
回复
搞定,问题正如dede22所说.感谢大家,结贴!!!
Jackword
2008-04-28
打赏
举报
回复
应该是对齐问题。 设置成一字节对齐 。project->settings->c/c++选项卡
Category中选Code Generation ,Struct member alignment选1Byte。
dede22
2008-04-28
打赏
举报
回复
headsize = 8;
bodysize = 0;
while (headsize > 0)
{
len = recv(gSocket,
puchead
, headsize, 0);
if (len <= 0)
{
continue;
}
else
{
headsize -= len;
}
}
红色处没有处理指针移动,数据被覆盖了
具体参看我的代码
wbohome
2008-04-28
打赏
举报
回复
沾包?
wb16860
2008-04-28
打赏
举报
回复
对,是TCP。
发送的包都是169个字节。
代码给大家贴上吧(win32环境)(为方便贴代码,简化了结构定义,错误处理等代码):
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include <io.h>
#include <tchar.h>
#include <Winsock2.h>
typedef struct MSG_HEAD_STRUCT
{
short usSize;
short usCmdId;
long slPid;
}MSG_HEAD_ST;
typedef struct MSG_BODY_STRUCT
{
short usType;//业务包类型
char msg[159];
}MSG_BODY_ST;
typedef struct MSG_STRUCT
{
MSG_HEAD_ST stHead;
MSG_BODY_ST stBody;
}MSG_ST;
SOCKADDR_IN gSynthAddr;
unsigned long ullRecvNum = 0;
SOCKET gSynthSocket;
SOCKET gSocket;
struct sockaddr_in synAddr;
int ulAddrLen = sizeof(struct sockaddr);
MSG_ST stMsg = {0};
void main()
{
int slRet;
int ulRet;
int headsize,bodysize;
int len;
char *puchead = (char *)&stMsg.stHead;
char *pucbody = (char *)&stMsg.stBody;
int i;
WSADATA gwsaSynthData;
WSAStartup(MAKEWORD(2,2),&gwsaSynthData);
gSynthSocket = socket(AF_INET, SOCK_STREAM, 0);
if(INVALID_SOCKET == gSynthSocket)
{
return;
}
/*通过配置读取*/
gSynthAddr.sin_family = AF_INET;
gSynthAddr.sin_port = htons(8586);
gSynthAddr.sin_addr.s_addr = htonl(INADDR_ANY);
slRet = bind(gSynthSocket, (SOCKADDR *)&gSynthAddr, sizeof(gSynthAddr));
if (slRet != 0)
{
return;
}
listen(gSynthSocket, 5);
ioctlsocket(gSynthSocket,FIONBIO,&ulRet); //非阻塞和阻塞都试过
while (1)
{
gSocket = accept(gSynthSocket, (SOCKADDR *)&synAddr, &ulAddrLen);
{
if (gSocket == INVALID_SOCKET)
{
continue;
}
else
{
printf("client connect success\n");
break;
}
}
}
while (1)
{
headsize = 8;
bodysize = 0;
while (headsize > 0)
{
len = recv(gSocket, puchead, headsize, 0);
if (len <= 0)
{
continue;
}
else
{
headsize -= len;
}
}
bodysize = stMsg.stHead.usSize - 8;
while (bodysize >0)
{
len = recv(gSocket, pucbody, bodysize, 0);
if (len <= 0)
{
continue;
}
else
{
bodysize -= len;
}
}
ullRecvNum++;
if (ullRecvNum % 10000 == 0)
{
printf("recv num:%d\n", ullRecvNum);
}
if (stMsg.stHead.usCmdId != 7)
{
printf("wrong msg,ullRecvNum:%d,type:%d\n", ullRecvNum, stMsg.stHead.usCmdId);
for(i = 0; i < stMsg.stHead.usSize; i++)
{
printf("0x%x,", ((char *)&stMsg)[i]);
if ((i % 19) == 0)
{
printf("\n");
}
}
printf("\n");
}
if (stMsg.stBody.usType > 7)
{
printf("gather msg type err,ullRecvNum:%d,type:%d\n", ullRecvNum, stMsg.stBody.usType);
for(i = 0; i < stMsg.stHead.usSize; i++)
{
printf("0x%x,", ((char *)&stMsg)[i]);
if ((i % 19) == 0)
{
printf("\n");
}
}
printf("\n");
}
memset((char *)&stMsg, 0, sizeof(MSG_ST));
}
}
dede22
2008-04-28
打赏
举报
回复
int buf[100];
int lstart = 0;
while(1)
{
ret = recv(fd,buf+lstart,10,0);
if(ret < 0 && errno != EINTR)
{
perror("recv err:");
}
if(lstart != 10)
{
lstart += ret;
}
else
{
break;
}
}
检查一下你的 接收代码吧,或者是你发送的部分多线程同步有问题
wbohome
2008-04-28
打赏
举报
回复
TCP?
wb16860
2008-04-28
打赏
举报
回复
回复sniperhuangwei:我把消息处理部分屏蔽掉,只进行接收还是会出现这种问题。回复hij333:是线程接收消息,其他线程处理消息,心跳等。
回复lala_benben:你所说的协议没对齐是指的什么?
回复sunyanlu:确实没清0,但是我清0后测试,问题依旧
回复maxwell:发出的包是固定的,我肯定没问题
另外,如果发包速度变小后(之前是每秒发送5000~10000的速度,改为每秒50~100),问题消失了。
sniperhuangwei
2008-04-28
打赏
举报
回复
检查下拆包的代码吧.
Maxwell
2008-04-28
打赏
举报
回复
检查你发出去的包是不是正确的,可能因为对齐或者其他什么原因,你发出去的包就是错的。
sunyanlu
2008-04-28
打赏
举报
回复
或者你忽略一下信号量看看
sunyanlu
2008-04-28
打赏
举报
回复
你的语句中有没有将受消息的变量置位清零
lala_benben
2008-04-28
打赏
举报
回复
应该是你的协议没对齐吧
hij333
2008-04-28
打赏
举报
回复
说一下,你是如何接收消息的?线程吗?
能把接收部分的关键代码贴出来吗?
socket
编程包的长度
Socket
编程中,包长度没有固定限制,但受到以太网MTU(1500字节)的影响。TCP
会
根据需要进行分片传输,而UDP则建议保持在1024至10K之间。Windows系统中,
Socket
缓冲区通常设为4K。TCP作为流协议,可以使用循环发送,而UDP需确保接收Buffer足够大以接收完整包。接收时,TCP可能
会
接收多个发包,需要进行组包处理,而UDP
会
丢弃Buffer过小无法容纳的数据。阻塞与非阻塞
Socket
在无数据时
会
有不同的处理方式。
socket
can
收到
的帧包乱序问题_TCP 协议如何解决粘包、半包问题
TCP协议作为流式协议可能导致数据包乱序或粘包。本文详细介绍了TCP协议的流式特性,并通过示例解释了粘包现象。接着讨论了解决粘包的三种方法:固定包长、包结束标志和包头+包体格式,同时提供了相应的处理流程和代码示例。最后,文章强调了正确处理粘包和半包的逻辑在多包接收场景中的重要性。
关于
socket
的各种
错误
码
本文详细解析了
Socket
编程中常见的
错误
代码及其处理方法,包括INVALID_
SOCKET
、
SOCKET
_ERROR、EINPROGRESS、EWOULDBLOCK等,阐述了如何在非阻塞模式下正确处理recv和send函数的
错误
返回。
Socket
通信bind
错误
本文探讨了在VxWorks环境下,
Socket
编程中遇到的bind
错误
问题及其解决方案。非正常退出导致的端口和地址占用问题,可以通过setsockopt函数设置SO_REUSEADDR选项解决。此外,还详细介绍了setsockopt函数的使用,包括各种套接字选项的意义和设置方法。
java
socket
消息
过大_java – Stomp spring web
socket
消息
超出大小限制
在使用Spring MVC Web应用程序中的Spring Web-
Socket
时遇到
消息
大小限制的问题。当尝试发送一个非常大的
消息
时,
会
收到
超出配置的
消息
缓冲区大小限制的
错误
。
C语言
70,039
社区成员
243,245
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章