初学者,求TCP/IP的粘包处理

jackey07 2010-07-14 05:07:11
刚开始学网络编程...
看书中例子,都是一发一收的
看好些文章,都说windows会进行优化,可能缓存后再发出, 就有了TCP/IP粘包问题要解决
求一个简单例子学习下
代码,资料都可以
谢谢各位大牛
...全文
354 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
weblai 2010-07-19
  • 打赏
  • 举报
回复
晕,TCP_NODELAY 是发送的。不是接收的。搞错了。
weblai 2010-07-19
  • 打赏
  • 举报
回复
如果不考虑优化的话

有一个开关,可以设定,是否粘包的。

TCP_NODELAY

lijianli9 2010-07-18
  • 打赏
  • 举报
回复
PACKHEADER
定义
struct PACKHEADER
{
char from[NAMELEN]; //发动端标识
char to[NAMELEN]; //接收端标识
int type; //包命令类型
int length; //包长度,
};
hhf 2010-07-18
  • 打赏
  • 举报
回复
两个方法,放入包长,或者指定包结束标志
jackey07 2010-07-18
  • 打赏
  • 举报
回复
谢谢各位热心观众...
晚上结贴
Icedmilk 2010-07-17
  • 打赏
  • 举报
回复
TCP在写程序时用的socket被称为流式套接字正如他的类型标示SOCK_STREAM

他被设计用来保证数据的有序安全

但是他并没有包的概念

虽然你的信息是一次一次发的,但是最后接受的就是一个数据流。

HTTP的做法是,HTTP的每个包对应了一个连接,就不存在粘包了
POP3和IMAP都是以 \r\n 作为分界
jackey07 2010-07-17
  • 打赏
  • 举报
回复
顶上去,跪求底层通信类高手指引
jackey07 2010-07-16
  • 打赏
  • 举报
回复
顶上去...持续等到到下周一
lijianli9 2010-07-15
  • 打赏
  • 举报
回复
7楼可用,
自己定义包头,里面有命令字信息,长度信息,以及其他的校验信息都可以放进来,
jackey07 2010-07-15
  • 打赏
  • 举报
回复
顶上去...
jackey07 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yschenwei 的回复:]
去年的时候吧,有人在这个版块开源了一段TCP发送,接收的代码,写的很好。
你仔细找找看。
当时我mark了,但是貌似CSDN时间长了也不能搜索了。
[/Quote]


没查到我能用的,谢谢
yschenwei 2010-07-15
  • 打赏
  • 举报
回复
去年的时候吧,有人在这个版块开源了一段TCP发送,接收的代码,写的很好。
你仔细找找看。
当时我mark了,但是貌似CSDN时间长了也不能搜索了。
jackey07 2010-07-15
  • 打赏
  • 举报
回复
期待中....感谢7楼,
只是内容不够...
jackey07 2010-07-15
  • 打赏
  • 举报
回复
各位大牛,请别嫌烦哦...
会了,就破门...
不会,就徘徊在门外...
哎,做技术是件苦差事,难于模棱两可...
I/O模型,数据收发处理,弄不会它们,难于自己架设服务端程序....

本贴只求数据收发..粘包处理...
jackey07 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 hastings 的回复:]
C/C++ code
这是网上流传很广泛的TCP粘包处理代码:
fd_set fdRead;
timeval TimeOut;
PACKHEADER *pHead = (PACKHEADER *)pBuffer;
int ret, nLeft = 0, idx = 0;

TimeOut.tv_sec = 0;
TimeOut.tv_usec = TIMEOUT;

FD_ZE……
[/Quote]

能否给PACKHEADER 的定义,谢谢
Eleven 2010-07-14
  • 打赏
  • 举报
回复
子定义应用层协议,加入包长,收到数据以后,先得到包的长度信息,然后根据长度接受后续的数据。
hastings 2010-07-14
  • 打赏
  • 举报
回复
这是网上流传很广泛的TCP粘包处理代码:
fd_set fdRead;
timeval TimeOut;
PACKHEADER *pHead = (PACKHEADER *)pBuffer;
int ret, nLeft = 0, idx = 0;

TimeOut.tv_sec = 0;
TimeOut.tv_usec = TIMEOUT;

FD_ZERO(&fdRead);
FD_SET(m_sock, &fdRead);

do
{
ret = ::select(0, &fdRead, NULL, NULL, &TimeOut);
if (ret == SOCKET_ERROR)
break;
if (ret > 0)
{
if (nLeft == 0)
ret = ::recv(m_sock, pBuffer, sizeof(PACKHEADER), 0);
else
ret = ::recv(m_sock, pBuffer + idx, nLeft, 0);
if (ret == 0) //对方连接中断
ret = SOCKET_ERROR;
if (ret == SOCKET_ERROR)
break;
if (nLeft == 0)
nLeft = pHead->length;
else
nLeft -= ret;
idx += ret;
}
else
break;
}
while (nLeft > 0);

不过你可能还得先了解一下select函数~~
jackey07 2010-07-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 shenyi0106 的回复:]
如果你用结构体发送,在加上ACK的话,一般不会出现此问题
如果用字符发送的话,就像楼上所说的,加个包长,先收包长,在收包
[/Quote]

期待有个实例,谢谢
xhuacmer 2010-07-14
  • 打赏
  • 举报
回复
这个的确是不大好处理的
shenyi0106 2010-07-14
  • 打赏
  • 举报
回复
如果你用结构体发送,在加上ACK的话,一般不会出现此问题
如果用字符发送的话,就像楼上所说的,加个包长,先收包长,在收包
加载更多回复(3)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧