在我们断开套接字的时候,应该尽量保证一个通信流程的完整,例如服务器或者客户端要关闭套接字,应该跟对方说:我要断开了,对方收到断开请求,有的时候要做响应的处理,比如保存当前状态,或者发送最后一帧数据报告断开前的状态,直接调用close()不是不是最好的方法
半关闭
服务器端,一般服务器主动断开连接的时候,才会用到半关闭,
半关闭的意思是,服务器关闭写通道,此时会给客户端发送一个EOF信息,客户端收到之后,知道服务器要关闭连接,此时客户端还可以向服务器发送最后一次信息,做最后的数据处理,服务器收到之后会完全关闭套接字
//int shutdown(int sock,int howto)
//sock 套接字
//howto 断开方式 SHUT_RX 断开输入流 SHUT_WR 断开输出流 SHUT_RDWR 同时断开
int main(int argc, char const *argv[])
{
int serv_sock,clnt_sock;
int clnt_addr_size;
char readbuf[READ_SIZE]={0};
struct sockaddr_in serv_addr,clnt_addr;
serv_sock=socket(PF_INET,SOCK_STREAM,0);
if(serv_sock==-1)
error_handling("creat socket error!");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(SERV_PORT);
if(bind(serv_sock,(struct socaddr *)&serv_addr,sizeof(serv_addr))==-1)
{
error_handling("bind error");
}
if(listen(serv_sock,5)==-1)
{
error_handling("listen error");
}
clnt_addr_size=sizeof(clnt_addr);
while(1){
clnt_sock=accept(serv_sock,(struct socaddr *)&clnt_addr,clnt_addr_size);//这里会阻塞,等待客户端连接
read(clnt_sock,readbuf,READ_SIZE-1);//读取客户端发送来的数据
write(clnt_sock,readbuf,sizeof(readbuf));
}
shutdown(serv_sock,SHUT_WR);//关闭输输出通道,客户端会收到EOF,就知道服务端要关闭了,向服务端发送最后一帧数据
read(clnt_sock,readbuf,READ_SIZE);//此时输入通道还未关闭,所以能读取客户端的数据
close(clnt_sock);//完全关闭
close(serv_sock);//完全关闭
return 0;
}
void error_handling(char * message)
{
printf("%s\n",message);
}