当前位置:网站首页>TCP的粘包问题代码说明
TCP的粘包问题代码说明
2022-07-23 05:44:00 【lhb2998658795】
1为什么出现沾包问题
TCP的底层有一个nagel算法 会将一定短的时间内的发往同一个接收端的 多个小的数据包组成一个整体 一起发送 而接收端无法区分数据的类型 所以就可能有冲突。
解决方法一:
是用sleep来将发送的东西分开,但是这样实际运用中并不靠谱并且实际传输中还有命令传输总不能发一个加一个sleep,而且sleep会是运行效率变慢所以这个方法实际开发中并不使用。
解决方法二:
就是将要发送的各种文件以及命令全部以结构体的方式打包发出,这样就不会出现沾包问题
2代码说明:
如果不存在,则回复给客户端文件不存在
如果存在,也要给客户端回复文件存在的消息
4.客户端收到服务的回复 如果不存在 则重新输入文件名
如果存在 则新建并打开文件 写|创建|清空
5.开始发送文件内容
6.文件结束发送 "****over*****" 给客户端
7.客户端收到 "****over****" 后就不要在recv 了
8.客户端退出 服务器等待下一次客户端的连接
3代码实现
客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <head.h>
//这里设置这个结构体主要是为了防止防沾包
#define N 512
typedef struct MSG_{
int num;
char buff[N];
}msg_t;
int jieshou_file(int sockfd,const char *filename)
{
int fd;
int ret=0;
msg_t tid;
if((fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666))==-1){
ERRLOG("open error3");
}
while(1){
memset(&tid,0,sizeof(tid));
if((ret=recv(sockfd,&tid,sizeof(tid),0))==-1){
ERRLOG("recv error");
}
if(!strncmp(tid.buff,"over",5)){
break;
}
write(fd,tid.buff,strlen(tid.buff));
}
return 0;
}
int main(int argc, char const *argv[])
{
int sockfd=0;
msg_t msg;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
ERRLOG("sockfd error");
}
struct sockaddr_in clientaddr;
clientaddr.sin_family=AF_INET;
clientaddr.sin_port=htons(atoi(argv[2]));
clientaddr.sin_addr.s_addr=inet_addr(argv[1]);
socklen_t clientaddr_len=sizeof(clientaddr);
if(connect(sockfd,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){
ERRLOG("connect error");
}
printf("connect successfully\n");
while(1){
//输入你想要下载文件的姓名
memset(&msg,0,sizeof(msg));
printf("Please enter the file name you want to downloadn >");
fgets(msg.buff,sizeof(msg.buff),stdin);
msg.buff[strlen(msg.buff)-1]='\0';
//将文件名字发送给服务器
if(send(sockfd,&msg,sizeof(msg),0)==-1){
ERRLOG("Failed to send file name to server");
}
//接受服务器反回来的消息
memset(&msg,0,sizeof(msg));
if(recv(sockfd,&msg,sizeof(msg),0)==-1){
ERRLOG("recv error1");
}
if(msg.num==2){
printf("There is no such file as you typed\n");
continue;
}else{
jieshou_file(sockfd,msg.buff);
break;
}
}
close(sockfd);
return 0;
}
服务器
#include <head.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define N 512
typedef struct MSG_{
int num;
char buff[N];
}msg_t;
int send_file(int acceptfd,const char *filename)
{
int fd;
int ret=0;
msg_t tid;
if((fd=open(filename,O_RDONLY))==-1){
ERRLOG("open filename error");
}
while((ret=read(fd,tid.buff,sizeof(tid.buff)))>0){
tid.num=ret;
if(send(acceptfd,&tid,sizeof(tid),0)==-1){
ERRLOG("send error1");
}
memset(&tid,0,sizeof(tid));
}
memset(&tid,0,sizeof(tid));
strcat(tid.buff,"over");
if(send(acceptfd,&tid,sizeof(tid),0)==-1){
ERRLOG("send error2");
}
return 0;
}
int is_file(msg_t *msg)//判断文件是否存在
{
if(msg==NULL){
ERRLOG("The ginseng error");
}
int fd;
if((fd=open(msg->buff,O_RDONLY))==-1){
if(errno==2){
msg->num=2;
return -1;
}
ERRLOG("open file error");
}
return 0;
}
int main(int argc, char const *argv[])
{
int sockfd=0;
int acceptfd=0;
msg_t msg;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
ERRLOG("sockfd error");
}
//网络信息结构体
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
socklen_t serveraddr_len=sizeof(serveraddr);
//将网络信息结构体进行绑定
if(bind(sockfd,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){
ERRLOG("bind error");
}
//将套接字设置为被动监听状态
if(listen(sockfd,5)==-1){
ERRLOG("listen error");
}
//设置一个新的网络信息结构体存储客户端信息
struct sockaddr_in clientaddr;
memset(&clientaddr,0,sizeof(clientaddr));
socklen_t clientaddr_len=sizeof(clientaddr);
if((acceptfd=accept(sockfd,(struct sockaddr*)&clientaddr,&clientaddr_len))==-1){
ERRLOG("accepfd error");
}
printf("客户[%s:%d]连接成功\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
while(1){
//接受客户端发来的文件名
memset(&msg,0,sizeof(msg));
if(recv(acceptfd,&msg,sizeof(msg),0)==-1){
ERRLOG("recv error3");
}
//验证是否有这个文件//当前目录
is_file(&msg);
//把是否有这个文件的信息发送给客户端
if(send(acceptfd,&msg,sizeof(msg),0)==-1){
ERRLOG("acceptfd error");
}
if(msg.num==2){
continue;
}else{
send_file(acceptfd,msg.buff);
}
}
close(acceptfd);
close(sockfd);
return 0;
}
4总结说明
该代码的要求是再文章的最后加一个over,如果不封装结构体,出现沾包问题,最后客户端收文件的时候他就找不到over,所以就会停不下了,用这个代码就是为了说明沾包问题,正常下载文件应该先向服务器获取对方的长度然后根据接受到的长度,让客户端停止接受。
边栏推荐
- 合成中文识别数据集的相关repo
- The CUDA version of pytorch installed by anconda is inconsistent with the CUDA version of the system
- 钢结构基本原理全面详细总结
- 【Autosar 存储Stack NVM】
- Interpretation of the paper: the interpretability of the transformer model of functional genomics
- 单片机学习笔记6--中断系统(基于百问网STM32F103系列教程)
- 【学习总结】
- 高等代数100道题及答案解析
- C语言中,对柔性数组的理解
- 博客搭建六:绑定自己域名的方法
猜你喜欢

Navicat for MySQL 安装教程

Blog Building II: next theme related settings beta

A comprehensive and detailed summary of the basic principles of steel structure

钢结构基本原理全面详细总结

输入三角形边长,求面积

二叉树基础oj练习-

Steel structure review questions

Interpretation of the paper: develop and verify the deep learning system to classify the etiology of macular hole and predict the anatomical results

Baidu Shen Shuo: focus on the scene, deeply cultivate the industry, and bring practical results to enterprise Digitalization

Anonymous upper computer V7 waveform display
随机推荐
博客搭建二:NexT主题相关设置beta
[AUTOSAR candrive 2. understand the mapping relationship between communication HOH, canid and pduid]
(1)ASIO
高电压技术学习总结
快速排序的按区间的三个版本及优化--友友们不一定了解
基于对象(Object Based)-两个经典类
Anconda安装的pytorch依赖的cuda版本和系统cuda版本不一致问题
Tencent cloud client command line tool tccli main process analysis
Interpretation of the paper: "deep-4mcw2v: sequence based predictor for identifying N4 methylcytosine (4mc) sites in E. coli"
表格个人简历
Data analysis (II)
博客搭建三:评论系统选择
动态规划——“换硬币问题”
Switch implements expression evaluation
Using pycaret for data mining: association rule mining
预处理指令#define,你真的懂了吗?
K-nucleotide frequencies (KNF) or k-mer frequencies
Configure TX1 system + set to solid-state disk startup
A comprehensive and detailed summary of the basic principles of steel structure
Data analysis of time series (I): main components