在计算机网络通信中,粘包是指在传输过程中,发送方发送的多个小数据包被接收方粘合在一起,形成一个大的数据包。这种现象通常出现在使用流式传输协议(如TCP)进行数据传输的情况下。
具体来说,TCP是一种面向连接的协议,它通过将数据划分为小的数据块(通常称为段)进行传输。发送方将这些数据块发送到网络,而接收方则负责将它们重新组装成原始的数据。然而,由于网络的不确定性和各种因素,接收方有时会在处理数据时将多个小数据块合并成一个大的数据块,从而产生粘包现象。
造成粘包的原因可能是多方面的,其中一些常见的因素包括:
为了解决粘包问题,通常采取以下策略:
这些方法有助于在数据传输过程中有效地处理粘包问题。选择哪种方法取决于具体的应用场景和需求。
分包解决粘包问题------------------------下一篇博客
完整代码:
server:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
int main(int, char**){
//1.创建套接字
int listen_sock=socket(AF_INET,SOCK_STREAM,0);
if (listen_sock==-1)
{
std::cerr<<"Fiald to create socket"<<std::endl;
return 1;
}
//2.绑定IP地址
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_addr.s_addr=INADDR_ANY;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(9999);
if(bind(listen_sock,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
{
std::cerr<<"Fiald to bind socket"<<std::endl;
return 1;
}
//3.监听套接字
if (listen(listen_sock,5)==-1)
{
std::cerr<<"Fiald to listen socket"<<std::endl;
return 1;
}
std::cout<<"server is listening"<<std::endl;
//4.接受客户端的连接
struct sockaddr_in client_addr;
socklen_t client_addr_len=sizeof(client_addr);
int client_sock=accept(listen_sock,(struct sockaddr*)&client_addr,&client_addr_len);
if (client_sock==-1)
{
std::cerr<<"Fiald to accept socket"<<std::endl;
return 1;
}
std::cout<<"a client connected"<<std::endl;
//5.数据交互
//接受消息
while (1)
{
char buffer[1024];
int read_size=read(client_sock,buffer,sizeof(buffer));
if (read_size<0)
{
std::cerr<<"Fiald to read"<<std::endl;
close(client_sock);
close(listen_sock);
exit(0);
}
std::cout<<"Received msg :"<<buffer<<std::endl;
}
// std::cout<<"Received to client :"<<buffer<<std::endl;
// std::string res_msg="Hello Client!";
// int wr=write(client_sock,res_msg.c_str(),res_msg.length());
// if (wr==-1)
// {
// std::cerr<<"Fiald to write"<<std::endl;
// return 1;
// }
close(client_sock);
close(listen_sock);
}
client:
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(){
//1.创建socket
int client_sock=socket(AF_INET,SOCK_STREAM,0);
if (client_sock==-1)
{
std::cerr<<"Faild to create socket"<<std::endl;
return -1;
}
//2.连接服务器
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
//server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr);
server_addr.sin_port=htons(9999);
if(connect(client_sock,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1){
std::cerr<<"Faild to connect socket"<<std::endl;
return -1;
}
std::cout<<"Connected to server"<<std::endl;
//3.数据交互
//发送消息
std::string msg1="hi";
std::string msg2="jack";
if(write(client_sock,msg1.c_str(),msg1.length())==-1){
std::cerr<<"Faild to write "<<std::endl;
return -1;
}
if(write(client_sock,msg2.c_str(),msg2.length())==-1){
std::cerr<<"Faild to write "<<std::endl;
return -1;
}
//接受消息
// char buffer[1024];
// if(read(client_sock,buffer,sizeof(buffer))==-1){
// std::cerr<<"Faild to read"<<std::endl;
// return -1;
// }
// printf("Receive to server :%s",buffer);
close(client_sock);
}