当前位置: 首页 > wzjs >正文

做图软件官方网站网站你懂我意思正能量晚上下载

做图软件官方网站,网站你懂我意思正能量晚上下载,广州公共资源交易中心交易平台,WordPress无法写博客头像一、TCP粘包简介 使用TCP 协议进行数据传输时,多个数据包被连续存储于缓存中,在对数据包进行读取时由于无法确定发送方的发送边界,而采用某一估测值大小来进行数据读取,使得发送方发送的若干个数据包到接收方接收时粘成一包&…

一、TCP粘包简介

        使用TCP 协议进行数据传输时,多个数据包被连续存储于缓存中,在对数据包进行读取时由于无法确定发送方的发送边界,而采用某一估测值大小来进行数据读取,使得发送方发送的若干个数据包到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
从上图中可以看出粘包主要分为两种情况:
        多个完整的数据包粘在一起
        一个完整的数据包被拆分成两部分与其它完整包粘在一起
TCP粘包问题会影响到有数据结构的数据包,会导致数据包解析出现问题.

二、TCP粘包原因分析

TCP 协议是面向连接的、可靠的、基于字节流的传输层通信协议出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。

粘包的根本原因

原因说明
TCP是字节流协议数据像水流一样没有固定边界,应用层需自行划分。
Nagle算法默认开启,会合并多个小数据包发送(减少网络拥塞)。
缓冲区机制发送缓冲区积累到一定大小或超时才会发送;接收缓冲区可能一次性读取多个包。

发送方引起的粘包是由TCP协议本身造成的

        TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP 会根据优化算法 (Nagle) 把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。

发送方一次性发送的数据大于 MTU ,则会发生拆包,将字节流进行切片分成多个包进行发送
接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象
        这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。

三、TCP解决方案

方式一 : 使用定长数据包,每次必须要读取固定长度的数据,(适用于数据长度固定的情景)

方式二:使用数据长度+数据的方式,先接收数据长度,再根据长度接收数据,(适用于数据长读度不固定的情景)

三, TCP粘包使用方式二解决实现

发送时,将数据长度+数据 作为数据包的内容,整体发送:
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
int main(int argc,char* argv[])
{
// 创建socket套接字的
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1){
perror("socket");
exit(EXIT_FAILURE);}
// 与服务器进行连接
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port=htons(atoi(argv[2]));
inet_aton(argv[1],&(addr.sin_addr));
int ret = connect(sockfd,(const struct sockaddr*)&addr,sizeof(struct
sockaddr_in));
if(ret==-1 ){
perror("connect");
close(sockfd);
exit(EXIT_FAILURE);}
// 向服务器端发送数据
char buf[]={"hello tcp!"};
for(int i=0;i<1000;i++){
int ret;
// 1、计算数据长度
int length = strlen(buf);
// 2、开辟空间
char* p_buf=(char*)malloc(length+4);// 使用整型来保存数据长度
// 3、对指定的空间赋值
memcpy(p_buf,&length,4);
memcpy(p_buf+4,buf,length);
//4、发送数据
ret = send(sockfd,p_buf,length+4,0);
if(ret == -1){
perror("send failed");
exit(EXIT_FAILURE);}}
close(sockfd);
return 0;
}

服务器端:

接收时,先接收数据长度,再根据数据长度固定接收数据:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BACKLOG 20
int main(int argc,char* argv[])
{
if(argc !=3){
fprintf(stderr,"%s ip port.\n",argv[0]);
exit(EXIT_FAILURE);}
// 创建socket
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1){
perror("socket failed.");
exit(EXIT_FAILURE);}
// 绑定ip+端口号
struct sockaddr_in addr;
int addrlen = sizeof(struct sockaddr_in);
bzero(&addr,addrlen);
addr.sin_family = AF_INET;
addr.sin_port=htons(atoi(argv[2]));
inet_aton(argv[1],&(addr.sin_addr));
int ret = bind(sockfd,(const struct sockaddr*)&addr,addrlen);
if(ret == -1){
perror("bind failed");
exit(EXIT_FAILURE);}
// 建立监听队列
ret = listen(sockfd,BACKLOG);
if(ret == -1){
perror("listen failed");
exit(EXIT_FAILURE);}
//建立连接
struct sockaddr_in client_addr;
int client_addrlen = sizeof(struct sockaddr_in);
int cfd = accept(sockfd,(struct
sockaddr*)&client_addr,&client_addrlen);
if(cfd == -1){
perror("accept failed.");
exit(EXIT_FAILURE);}
// 打印客户端的信息
ssize_t rbytes = 0;
char buf[1024]={0};
while(1){
int length = 0;
int total_received = 0;//已经接收的字节数
// 1、先接收数据长度
rbytes = recv(cfd,&length,4,0);
if(rbytes == -1){
perror("recv data length failed");
exit(EXIT_FAILURE);}
memset(buf,0,sizeof(buf));
// 接收客户端的消息(注意:使用新的文件标识符)
while(1){
printf("length=%d\n",length);
rbytes = recv(cfd,buf+total_received,lengthtotal_received,0);
if(rbytes==-1){
perror("server recv failed.");
exit(EXIT_FAILURE);}
else if(rbytes == 0){
fprintf(stderr,"stream socket shutdown.\n");
exit(EXIT_FAILURE);}
else{
total_received += rbytes;
if(total_received == length)//接收完成{
printf("recv message: %s\n",buf);
break;}}}
// 休眠一秒,发送数据比接收数据快
sleep(1);}
return 0;
}
运行结果:

文章转载自:

http://aLlPkCmR.mpLLd.cn
http://10D044hc.mpLLd.cn
http://AWAeOwVS.mpLLd.cn
http://dW3VwGEg.mpLLd.cn
http://rjPzWCUE.mpLLd.cn
http://HozfkFd4.mpLLd.cn
http://lFDPK9Ua.mpLLd.cn
http://fzhCf5dm.mpLLd.cn
http://I5QptYzH.mpLLd.cn
http://t8jHJjwq.mpLLd.cn
http://qB365FIH.mpLLd.cn
http://SbJMqAoj.mpLLd.cn
http://JrENiGKn.mpLLd.cn
http://DdiBSCGq.mpLLd.cn
http://u07uoJGL.mpLLd.cn
http://VKOvamkG.mpLLd.cn
http://jF89seP4.mpLLd.cn
http://lTA0kGlI.mpLLd.cn
http://2Vpy5sv0.mpLLd.cn
http://lZm9ywZc.mpLLd.cn
http://dT3UM7f2.mpLLd.cn
http://ZZo1Q3nG.mpLLd.cn
http://r4ki4Fgo.mpLLd.cn
http://kQb5VvNj.mpLLd.cn
http://oAjy6riU.mpLLd.cn
http://bXetcjj6.mpLLd.cn
http://0wA0k6A2.mpLLd.cn
http://gniQ5JLE.mpLLd.cn
http://9dqp7aLf.mpLLd.cn
http://3KkC7uiq.mpLLd.cn
http://www.dtcms.com/wzjs/677442.html

相关文章:

  • 招商网站搭建费用最近的战争新闻大事
  • 响应式网站的缺点在虚拟主机上建设多个网站
  • 丽水网站建设哪家好网站广告代码怎么添加
  • 是什么网站建设极客 pthyon 做网站
  • 做网站jijianjianzhan网站建设和维护视频
  • 免费做网站凡科湖北网站设计制作开发
  • 深圳网站优讳化wordpress标签样式表
  • 网站开发与桌面应用开发兰考网站建设
  • 网站建设 seo模块重慶网站开发
  • 手机网站制作良心服务flash网站模板修改
  • 中小企业公共服务平台网站建设企业网站建设一条龙多少钱
  • 网站ui设计包括哪些原则网站的交互体验
  • 闭站保护期间网站能够打开吗网页设计好学吗
  • 烟台百度网站排名wordpress 主题制作 评论
  • 哪儿能做邯郸网站建设网站皮肤是怎么做的
  • 做淘宝头像的网站内部搜索引擎优化
  • 学做游戏 网站凯里官网
  • 网站APP注册做任务中瑞网络网站建设流程
  • phpcms网站转移万维网站续费多少一年
  • 有关性的网站网站 png
  • 网站建设潮州家电电商平台排名
  • 德州市建设街小学官方网站商标设计在线
  • 濮阳网站开发wordpress 模板森林
  • 手机建站平台哪个好设计师接单的十个网站
  • 第一次做怎么放进去视频网站信用卡申请网站建设
  • 怎样查找自己建设的网站建设银行国际互联网站
  • 中国最受欢迎的网站做响应式网站最大宽度
  • 三明网站建设公司小程序获取wordpress背景音乐
  • 做网站6000左右的电脑邯郸去哪做网站改版
  • 怎么在别人网站上做锚文本链接如何做企业网站推广产品