目录
半关闭
半关闭 :当 TCP 链接中 A 向 B 发送 FIN 请求关闭,另一端 B 回应 ACK 之后(A 端进入 FIN_WAIT_2 状态),并没有立即发送 FIN 给 A,A 方处于半连接状态(半开关),此时 A 可以接收 B 发 送的数据,但是 A 已经不能再向 B 发送数据。
端口复用
端口复用最常用的用途是:
1.防止服务器重启时之前绑定的端口还未释放
2.程序突然退出而系统没有释放端口
server:
#include<stdio.h>
#include<ctype.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char *argv[]){
//创建socket
int lfd = socket(PF_INET,SOCK_STREAM,0);
if(lfd==-1){
perror("socket");
return -1;
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons(9999);
int optval=1;
setsockopt(lfd,SOL_SOCKET,SO_REUSEPORT,&optval,sizeof(optval));
//绑定
int ret = bind(lfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(ret==-1){
perror("bind");
return -1;
}
//监听
ret = listen(lfd,8);
if(ret==-1){
perror("listen");
return -1;
}
//接受客户端连接
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
int cfd = accept(lfd,(struct sockaddr*)&cliaddr,&len);
if(cfd==-1){
perror("accept");
return -1;
}
//获取客户端信息
char clilp[16];
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,clilp,sizeof(clilp));
unsigned short cliPort = ntohs(cliaddr.sin_port);
//输出客户端信息
printf("client's ip is %s,and port is %d\n",clilp,cliPort);
//接收客户端发来的数据
char recvBuf[1024]={0};
while(1){
int len=recv(cfd,recvBuf,sizeof(recvBuf),0);
if(len==-1){
perror("recv");
return -1;
}else if(len==0){
printf("客户端已经断开连接...\n");
break;
}else if(len>0){
printf("read buf = %s\n",recvBuf);
}
//小写转大写
for(int i=0;i<len;i++){
recvBuf[i]=toupper(recvBuf[i]);
}
printf("after buf = %s\n",recvBuf);
//大写字符串传回客户端
ret = send(cfd,recvBuf,strlen(recvBuf)+1,0);
if(ret==-1){
perror("send");
return -1;
}
}
close(cfd);
close(lfd);
return 0;
}
client:
#include<stdio.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int main(){
//创建socket
int fd = socket(PF_INET,SOCK_STREAM,0);
if(fd==-1){
perror("socket");
return -1;
}
struct sockaddr_in seraddr;
inet_pton(AF_INET,"192.168.108.128",&seraddr.sin_addr.s_addr);
seraddr.sin_family=AF_INET;
seraddr.sin_port=htons(9999);
//连接服务器
int ret = connect(fd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret==-1){
perror("connect");
return -1;
}
while(1){
char sendBuf[1024]={0};
fgets(sendBuf,sizeof(sendBuf),stdin);
write(fd,sendBuf,strlen(sendBuf)+1);
//接受
int len = read(fd,sendBuf,sizeof(sendBuf));
if(len==-1){
perror("read");
return -1;
}else if(len>0){
printf("read buf = %s\n",sendBuf);
}else {
printf("服务器已经断开连接...\n");
break;
}
}
close(fd);
return 0;
}