Felixxx 的学生作业:
原因:TCP 是“流式协议”,它不保留消息边界
1.发送方合并(Nagle 算法)
小数据不会立刻发,等攒够了或超时再发 → 多次 send() 合成一个包
2.接收方缓冲(应用层读取时机)
对方可能一次 recv() 读走多个 send() 的数据
或一次 send() 的数据被分成多次 recv() 读(这叫“拆包”)
client
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char* argv[]){
int sockfd;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1){
perror("error for socket");
return -1;
}
struct sockaddr_in addr;
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
addr.sin_addr.s_addr = inet_addr(argv[1]);
int res = connect(sockfd,(const struct sockaddr* )&addr,sizeof(addr));
if(res==-1){
perror("error for connect");
return -1;
}
ssize_t rbytes=0,sbytes = 0;
char buffer[] = {"hello server"};
while(1){
sbytes = send(sockfd,buffer,strlen(buffer)+1,0);
}
close(sockfd);
return 0;
}
server
#include
#include
#include
#include
#include
#include
#include
#include
const int BLOCKSOCK = 100;
int main(int argc,char* argv[]){
if(argc!=3){
perror("input invalid");
return -1;
}
int sockfd;
ssize_t rbytes = 0,sbytes = 0;
char buffer[1024] = {0};
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1){
perror("error for socket");
return -1;
}
struct sockaddr_in addr;
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
addr.sin_addr.s_addr = inet_addr(argv[1]);
int res = bind(sockfd,(const struct sockaddr*)&addr,sizeof(addr));
if(res==-1){
perror("error for bind");
return -1;
}
res = listen(sockfd,BLOCKSOCK);
if(res==-1){
perror("error for listen");
return -1;
}
struct sockaddr_in client;
bzero(&client,sizeof(client));
socklen_t len = sizeof(client);
int sockfdc = accept(sockfd,(struct sockaddr*)&client,&len);
if(sockfdc==-1){
perror("error for accept");
return -1;
}
while(1){
rbytes = recv(sockfdc,buffer,sizeof(buffer),0);
if(rbytes==0){
printf("quit\n");
break;
}
else if (rbytes>0){
printf("receive %s \n",buffer);
if(strncmp(buffer,"quit",4)==0){
printf("quit\n");
break;
}
}else{
perror("error for recv");
return -1;
}
sleep(1);
}
close(sockfdc);
close(sockfd);
return 0;
}