/*************************************
文件名: server.c
TCP 组包和拆包实现算法
作者: 马中海
QQ: 284358503
Email: zhonghaima001@163.com
*/
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 1024*5
//#define TCP_PACK_DEBUG 1
int main()
{
int nBufuseLen=0; //缓冲区里用到的长度
int nRevOnceLen=0; //read 一次读到的长度
int nPackLen=0; //每一包的长度,包括头和两个长度和尾字节
int bufSize=BUF_SIZE;
unsigned char buf[BUF_SIZE]; //read 的缓存
int i=0;
int sfp,nfp; /* 定义两个描述符 */
struct sockaddr_in s_add,c_add;
int sin_size;
unsigned short portnum=6000; /* 服务端使用端口 */
printf("Hello,welcome to my server !\r\n");
sfp = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == sfp)
{
printf("socket fail ! \r\n");
return -1;
}
printf("socket ok !\r\n");
/* 填充服务器端口地址信息,以便下面使用此地址和端口监听 */
bzero(&s_add,sizeof(struct sockaddr_in));
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr=htonl(INADDR_ANY); /* 这里地址使用全0,即所有 */
s_add.sin_port=htons(portnum);
/* 使用bind进行绑定端口 */
if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
{
printf("bind fail !\r\n");
return -1;
}
printf("bind ok !\r\n");
/* 开始监听相应的端口 */
if(-1 == listen(sfp,5))
{
printf("listen fail !\r\n");
return -1;
}
printf("listen ok\r\n");
// while(1)
{
// char buf[1027];
// int readlen;
sin_size = sizeof(struct sockaddr_in);
/* accept服务端使用函数,调用时即进入阻塞状态,等待用户进行连接,在没有客户端进行连接时,程序停止在此处,
不会看到后面的打印,当有客户端进行连接时,程序马上执行一次,然后再次循环到此处继续等待。
此处accept的第二个参数用于获取客户端的端口和地址信息。
*/
nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size);
if(-1 == nfp)
{
printf("accept fail !\r\n");
return -1;
}
printf("accept ok!\r\nServer start get connect from %#x : %#x\r\n",ntohl(c_add.sin_addr.s_addr),ntohs(c_add.sin_port));
/* 这里使用write向客户端发送信息,也可以尝试使用其他函数实现 */
if(-1 == write(nfp,"hello,welcome to my server \r\n",32))
{
printf("write fail!\r\n");
return -1;
}
//头0xF9 两个长度字节 数据 尾0xF8
while(1)
{
#ifdef TCP_PACK_DEBUG
{
printf("bufSize = %d ,nBufuseLen = %d\n",bufSize,nBufuseLen);
}
#endif
if(bufSize>nBufuseLen)
{
nRevOnceLen=read(nfp,buf+nBufuseLen,bufSize-nBufuseLen);
nBufuseLen=nBufuseLen+nRevOnceLen;
#ifdef TCP_PACK_DEBUG
{
printf("nBufuseLen = %d>3\n",nBufuseLen);
}
#endif
/*
printf(" nRevOnceLen data:\n");
for(i=0; i<nRevOnceLen; i++)
{
printf(" 0x%x ",buf[i]&0xFF);
}
printf(" \n");
*/
}
else
{
printf("buf if full\n");
}
while(nBufuseLen>3) //用到的大于3个字节
{
/* printf(" nBufuseLen data:\n");
for(i=0; i<nBufuseLen; i++)
{
printf(" 0x%x ",buf[i]&0xFF);
}
printf(" \n");
*/
#ifdef TCP_PACK_DEBUG
{
printf("buf[0] = 0x%x \n",buf[0]&0xFF);
}
#endif
if((buf[0]&0xFF)==0xF9) //头
{
nPackLen=(buf[1]*256)+buf[2];
#ifdef TCP_PACK_DEBUG
{
printf("nBufuseLen=%d ,nPackLen=%d\n",nBufuseLen,nPackLen);
}
#endif
if(nBufuseLen>=nPackLen) //大于和=
{
#ifdef TCP_PACK_DEBUG
{
printf("buf[nPackLen-1] = 0x%x \n",buf[nPackLen-1]&0xFF);
}
#endif
if((buf[nPackLen-1]&0xFF)==0xF8) //尾
{
//找到一包数据,所有的数据都往前移动nPackLen个字节
#ifdef TCP_PACK_DEBUG
{
printf("head 0x%x length %d tail 0x%x \n", buf[0]&0xFF,nPackLen,buf[nPackLen-1]&0xFF);
}
#endif
for(i=0; i<nBufuseLen-nPackLen; i++)
{
buf[i]=buf[nPackLen+i];
}
nBufuseLen=nBufuseLen-nPackLen; //用到的字节变小了
// continue; //不要read了
}
else
{
#ifdef TCP_PACK_DEBUG
printf("buf[%d-1]=0x%x,(buf[0]!=0xF8)\n",nPackLen,(buf[nPackLen-1]!=0xF8)); //这里应该不会执行
for(i=0; i<5; i++)
{
printf(" 0x%x ",buf[i]&0xFF);
}
printf(" \n");
#endif
printf(" (buf[nPackLen-1]&0xFF)!=0xF8 \n");
nBufuseLen=0; //清除错误的包 //这里应该不会执行
break;
}
}
else
{
#ifdef TCP_PACK_DEBUG
printf(" nBufuseLen<=nPackLen\n");
#endif
break;
}
}
else
{
printf(" (buf[0]!=0xF9)\n"); //这里应该不会执行
nBufuseLen=0; //清除错误的包 //这里应该不会执行
break;
}
}
/*
if((0xFF&buf[0])!=0xF2)
{
printf("readlen = %d buf 0x%x 0x%x 0x%x \n",readlen,0xFF&buf[0],0xFF&buf[1],0xFF&buf[2]);
}
if(readlen!=1027)
printf("readlen = %d buf 0x%x 0x%x 0x%x \n",readlen,0xFF&buf[0],0xFF&buf[1],0xFF&buf[2]);
*/
}
// close(nfp);
}
// close(sfp);
return 0;
}相关推荐
SAP SD 顾问面试问题 consultant interview questionnaire
以下是我个人目前面试团队 SD顾问问题的小结,希望对大家有所帮助, 也可能有回答错误的地方,希望同行不吝赐教。 也希望各位顾问们讲你们遇到的一些面试问题做个跟贴,方便大家共同进步,谢谢。 面试问题清单: 一、销售订单类型影响: 可用性检查,交货类型,输出,信贷,定价,需求,报表,合作伙伴,文本,不完整日志,交货开票,订单开票,公司间开票,统计组,屏幕顺序组,参数文件...
Socket 中级篇(四) TCP组包、粘包、拆包的原理
第一章、简介 1、这篇博客我想阐述什么? 在利用Socket+Tcp通信中,如果不采用开源库(比如SuperSocket)来实现,那么就是自己写了。既然自己写的东西,必须考虑稳定性、有效性、可行性等等。 直到今天,在用Socket/TCP做视频监控过程中,当网络较慢时,Socket/tcp通信,并不能一次性地把发送缓存区的数据发送出去。如果接受端不做处理,而是按接...
Marin说PCB之LPDDR5的布线注意事项--03
这个规则中是把每个字节中的WCK to RDQS 以及DM / DQ to WCK等长规则都加到了DM / DQ这个等长规则中去了,因为芯片手册上的设计要求中的DM / DQ这个group的等长误差是+-50MIL, WCK to RDQS的等长group的规则是62.5MIL,DM / DQ to WCK等长group的规则是相对松一些是150MIL。其实上面的等长规则还是建少了一些的,例如手册上要求的每个channel的WCK0:1,WCK2:3等长误差在+-488MIL,这个规则建议还是补上去吧。
详解一次完整的数据包传输过程 -- 层层递进
文章目录 例子 PC1 发送http请求到ServerStep1: PC1封装数据包Step 2: 数据到达集线器Step3: 数据到达R1Step4: 数据到达R2Step5: 交换机处理Step6: 服务器处理反向传输总结 题记:本文主要是摘自CCNA指南中讲的,再加上自己的理解,详细阐述一次完整的数据传输过程。之前在考CCIE的时候也看过,后来有些忘记,特总结记录。 读此文章之前,先弄懂下面5个基本知识点: 封装报文是从上层到下层(应用层 --> 传输层 --> ..
初级文章【西门子】字符拼接成字符串
针对S7-400极其以下PLC,1200往上据说有专门的块了呢,首先,我是不用库的,需要什么函数会自己写,OK进入正题。 首先,我们有一个DB块,里面有14个char,一个14位的char数组和一个14位的string。如下图。 我们的目的是将char1-char10拼接成一个string。 第一种方式:第一步,将char放进数组。 相信大家都能看明白,但是我还是要解释解释 L取值2 T赋值到临时变量DBNO(INT) OPN DB [#DBNO]获取DB块,这一句.
010、Zephyr RTOS开发环境搭建(Docker)
摘要 本文分享了使用Docker搭建Zephyr RTOS开发环境的实践经验。作者通过团队新人配置环境的真实案例,指出传统安装方式存在版本冲突、缓存污染等问题,而Docker方案能确保环境一致性。文章详细介绍了自定义Docker镜像的设计思路,重点解决工具链版本匹配、Python虚拟环境隔离等问题,将镜像体积从2GB优化到800MB。提供了从拉取镜像到点亮LED的完整工作流程,并总结了USB设备直通、文件权限、缓存问题等常见陷阱。还探讨了多阶段构建、CI集成等进阶用法,同时客观分析了Docker方案的局限性
代码笔记 | TCP 组包和拆包算法
/************************************* 文件名: server.c TCP 组包和拆包实现算法 */ #include #include #include #include #include #include #include #include #include #define BUF_SIZE 1024*
[VT虚拟化驱动]正式启动VT
文章目录前言一、vmlaunch正式开始虚拟化二、使用步骤1.引入库2.读入数据总结 前言 本章开始真正实现一个最简单的VT框架,当然,只是能跑起来一个VT驱动了,没有并包括EPT,EPT后面再讲 提示:以下是本篇文章正文内容,下面案例可供参考 一、vmlaunch正式开始虚拟化 执行VMLAUNCH指令执行后,就正式进入虚拟化了,再该指令执行之前,得先保存Guest当前的环境,执行完VMLAUNCH后,要恢复Guest的环境,让Guest就像什么都没发生一样,所以需要保存和恢复Guest的各种寄存器的值
SOCKET的封包与拆包
SOCKET的封包与拆包 转载汤姆瑞德尔最后发布于2017-04-10 17:15:15阅读数 573收藏 展开 对于基于TCP开发的通讯程序,有个很重要的问题需要解决,就是封包和拆包.自从我从事网络通讯编程工作以来(大概有三年的时间了),我一直在思索和改进封包和拆包的方法.下面就针对这个问题谈谈我的想法,抛砖引玉.若有不对,不妥之处,恳求大家指正.在此先谢过大家了. 一.为什么...
基于深度学习的堰塞坝表层颗粒物质识别研究
本文提出一种基于深度学习的堰塞坝表层颗粒物质智能识别方法,针对颗粒分布散乱、背景复杂的问题,采用"大颗粒逐个识别、密集小颗粒分块识别"策略。结合Mask R-CNN、SLIC和AlexNet构建识别模型,通过无人机影像实现自动识别。实验表明该方法精度超过90%,具备迁移能力。文章提供了Python实现代码,涵盖数据预处理、SLIC分割、模型构建(Mask R-CNN和AlexNet)及训练流程,为堰塞坝应急抢险提供技术支持。
【WorkBuddy专栏58】腾讯为什么要「自己打自己」——7款AI智能体产品全景对比与「赛马」逻辑深度拆解
【WorkBuddy专栏57】你的左侧空间不是「日任务清单」——工作空间才是 WB 变聪明的核心秘密
tcp 发送数据长度比预设缓存大_阿里Java一面:熟悉TCP粘包、拆包?说说粘包、拆包产生原因...
大家好,我是小寒!今天给小伙伴介绍一下TCP粘包、拆包!有自己看法的也可以在评论区留言探讨,也可以转发关注下我以后会长期分享!此文是转载于博客园一位博主的写作链接:https://www.cnblogs.com/qdhxhz/p/10277239.html一、TCP粘包、拆包图解假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到字节数是不确定的,故可能存在以下四种情况:服务端分...
Jetson agx Orin 适配Xenomai4
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况
主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。
efm32 入门.pdf
本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。
粘包、拆包
粘包、拆包发生原因 (1)socket缓冲区与滑动窗口 先明确一个概念:每个TCP socket在内核中都有一个发送缓冲区(SO_SNDBUF)和一个接收缓冲区(SO_RCVBUF),TCP的全双工的工作模式以及TCP的滑动窗口便是依赖于这两个独立的buffer以及此buffer的填充状态。SO_SNDBUF和SO_RCVBUF 在windows操作系统中默认情况下都是8K ...
最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版
Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。
网络通信--封包和拆包
转载自:http://blog.youkuaiyun.com/fengge8ylf/article/details/793808 对于基于TCP开发的通讯程序,有个很重要的问题需要解决,就是封包和拆包.自从我从事网络通讯编程工作以来(大概有三年的时间了),我一直在思索和改进封包和拆包的方法.下面就针对这个问题谈谈我的想法,抛砖引玉.若有不对,不妥之处,恳求大家指正.在此先谢过大家了.
Probability and Statistics - 4th edition
Probability and Statistics - 4th edition
tcp黏包与拆包
目录 1.黏包2.封包与拆包 1.黏包 1.为什么出现黏包 1.发送方原因 tcp默认会使用Nagle算法,而Nagle算法主要做两件事。1)只有上一个分组得到确认,才会发送下一个分组 2)收集多个小分组,在一个确认到来时一起发送。2.接收方原因 tcp接收到分组时,并不会立刻送至应用层处理,或者说应用层并不一定会立即处理;实际上,tcp将收到的分组保存至接收缓存...
TCP粘包拆包问题
原文:https://my.oschina.net/andylucc/blog/625315 摘要: 粘包拆包问题是处于网络比较底层的问题,在数据链路层、网络层以及传输层都有可能发生。我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生这个问题,因此这篇文章只讨论发生在传输层的TCP粘包拆包问题。 粘包拆包问题是处于网络比较底层的问题,在数据链路层、网络层以及传输...
TCP拆包粘包问题
对于刚接触TCP网络编程的人有时候碰到一些问题,比如当客服端发送一串消息到服务端,服务端只收到消息的一半,或者当连续发送两个消息到服务端,服务端同时收到这两个消息但无法解析。这就是今天要讲的TCP拆包粘包现象。 拆包粘包产生的原因 我们可以通过以下图进行说明 1.图一是正常的情况下包的发送和...
[转载]封包和拆包
原文:http://blog.youkuaiyun.com/fengge8ylf/archive/2006/06/13/793808.aspx 对于基于TCP开发的通讯程序,有个很重要的问题需要解决,就是封包和拆包.自从我从事网络通讯编程工作以来(大概有三年的时间了),我一直在思索和改进封包和拆包的方法.下面就针对这个问题谈谈我的想法,抛砖引玉.若有不对,不妥之处,恳求大家指正.在此先谢过大家了.一.为什么...
IPsec传输模式下ESP报文的装包和拆包过程
原创文章,拒绝转载 装包过程 总体流程图 过程描述 在原IP报文中找到TCP报文部分,在其后添加相应的ESP trailer信息。 ESP trailer 包含三部分:Padding,Pad length 和 Next header。Padding 即使用块加密时,最后一个数据块长度不足时所做的填充。Pad length 指填充的长度,方便拆包时找到用来填充的数据段。Next header...
TCP传输协议中如何解决丢包问题
TCP在不可靠的网络上实现可靠的传输,必然会有丢包。TCP是一个“流”协议,一个详细的包将会被TCP拆分为好几个包上传,也是将会把小的封裝成大的上传,这就是说TCP粘包和拆包难题。 ...
tcp粘包分析
tcp粘包分析
封包和拆包
转载:作者:fengge8ylf 博客:http://blog.youkuaiyun.com/fengge8ylf 对于基于TCP开发的通讯程序,有个很重要的问题需要解决,就是封包和拆包.自从我从事网络通讯编程工作以来(大概有三年的时间了),我一直在思索和改进封包和拆包的方法.下面就针对这个问题谈谈我的想法,抛砖引玉.若有不对,不妥之处,恳求大家指正.在此先谢过大家了. 一.为什么基于TCP的通讯程序...
转载:TCP通信粘包问题分析和解决(完整版)
在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小、数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 对于UDP,不会使用块的合并...
IOS开发Scoket接受报文不全(分多次接受)的TCP粘包问题
转载自:http://blog.youkuaiyun.com/zhangxinrun/article/details/6721495 这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一 .两个简单概念长连接与短连接: 1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然
1809



被折叠的 条评论
为什么被折叠?



