代码笔记 | TCP 组包和拆包算法
来源:互联网 发布:阿里云邮箱密码找回 编辑:程序博客网 时间:2024/05/17 07:40
/*************************************文件名: server.cTCP 组包和拆包实现算法 */#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;}
0 0
- 代码笔记 | TCP 组包和拆包算法
- TCP 组包和拆包算法
- TCP 组包和拆包算法-转载
- TCP粘包和拆包原因
- TCP 粘包 和 拆包
- TCP粘包和拆包原因
- tcp粘包和nagle算法
- tcp粘包和拆包、断包
- Netty 权威指南笔记(三):TCP 粘包和拆包
- Netty4学习笔记(二) TCP黏包/拆包解决办法
- TCP粘包、拆包
- TCP粘包,拆包
- Netty权威指南之TCP粘包和拆包
- Netty中处理TCP粘包和拆包
- Netty (三) TCP粘包和拆包解决方案
- tcp粘包和拆包的处理方案
- tcp粘包和拆包的处理方案
- tcp粘包和拆包的处理方案
- c++子类和父类指针的转换
- 购物车---JAVA-WEB
- df 命令详解
- 代码笔记 | 洗牌算法
- IntelliJ IDEA 常用快捷键
- 代码笔记 | TCP 组包和拆包算法
- iOS开发集成友盟,新浪微博登录授权失败,responseCode等于5051
- Google推荐的图片加载库Glide介绍
- Android中Fiddler的使用技巧
- Struts2的初识
- 代码笔记 | PHP实现N*M的字符矩阵90度旋转
- POJ 2484A Funny Game
- 大型支付系统后台对账系统的控制和管理
- C++四种强制类型转换运算符总结