RST_FIN
来源:互联网 发布:吊带承重数据 编辑:程序博客网 时间:2024/05/30 02:23
FIN RST
server.c
#include <sys/socket.h>#include <netdb.h>#include <sys/types.h>#include <errno.h>#include <netinet/in.h>#include <arpa/inet.h>//inet_ntop,没有头文件编译过得去,但是运行出错#include <stdio.h>//#include <strings.h>#include <unistd.h>//fork#include <sys/wait.h>int main(){ int sockfd = socket(AF_INET,SOCK_STREAM,0); if (sockfd < 0) { perror("create socket error"); } struct sockaddr_in server_sock_addr; bzero(&server_sock_addr,sizeof(struct sockaddr_in)); server_sock_addr.sin_family = AF_INET; server_sock_addr.sin_port = htons(12345); inet_pton(AF_INET,"127.0.0.1",(char *)&server_sock_addr.sin_addr); int ret = bind(sockfd,(struct sockaddr *) &server_sock_addr,sizeof(server_sock_addr)); if(ret < 0) perror("bind error"); ret = listen(sockfd,1); if(ret < 0) perror("listen error"); struct sockaddr_in client_sock_addr ; int len; int client_fd; client_fd = accept(sockfd,(struct sockaddr *) &client_sock_addr,&len); if( client_fd < 0) perror("accpet error"); char content [5]; char msg[100] = "cwd"; while(1) { int n = read(client_fd,content,sizeof(content)); if(n == 0)//n == 0表示对方发送了FIN,发生在接受RST之前,若是在接受RST之后,则erron为ECONNRESET,阻塞情况下返回值只有>0和<0, { printf("read %d byte\n",n); int len = write(client_fd,msg,100);//引起对方发送RST printf("write %d byte ok\n",len);//client已经关闭,但是发送扔能成功,但是发送了字节是100 len = read(client_fd,content,sizeof(content));//读到RST printf("recv %d byte after recv RST\n",len); len = write(client_fd,msg,100);//对于接收到RST的进程再次写则收到sigpipe信号,默认行为是终止进程 if(len < 0) { perror("read error"); } break; } else { content[n] = '\0'; printf("recv content is %s\n",content); } } /* * getpeername * getsockname printf("%d\n",client_fd); struct sockaddr_in sockaddrtmp; int length = sizeof(struct sockaddr_in); ret = getsockname(client_fd,(struct sockaddr *)&sockaddrtmp,&length); if(ret == -1) perror("getsockname error"); printf("server port = %d\n",htons(sockaddrtmp.sin_port));//网络字节序 printf("server family = %d\n",sockaddrtmp.sin_family); char addr[16]; char *ptr; ptr = inet_ntop(AF_INET,(const void *)&sockaddrtmp.sin_addr,addr,16);//网络字节序 printf("server addr = %s\n",ptr); //printf("address = %s\n",inet_ntoa(sockaddrtmp.sin_addr)); struct sockaddr_in peer_sock; length = sizeof(peer_sock); ret = getpeername(client_fd,(struct sockaddr*)&peer_sock,&length); if(ret == -1) perror("getpeername error"); printf("peer port = %d\n",htons(peer_sock.sin_port));//网络字节序 printf("peer family = %d\n",peer_sock.sin_family); printf("peer address = %s\n",inet_ntop(AF_INET,&peer_sock.sin_addr,addr,16)); */ return 0;}
client.c
#include <sys/socket.h>#include <netdb.h>#include <sys/types.h>#include <stdio.h>//#include <arpa/inet.h>//int main(){ int fd = socket(AF_INET,SOCK_STREAM,0); if(fd < 0) perror("socket error"); struct sockaddr_in server_sock_addr; server_sock_addr.sin_family = AF_INET; server_sock_addr.sin_port = htons(12345); inet_pton(AF_INET,"127.0.0.1",&server_sock_addr.sin_addr); /* int ret = bind(fd, (struct sockaddr*)&server_sock_addr, sizeof(client_sock_addr)); if(ret < 0) perror("bind error"); */ int ret = connect(fd,(struct sockaddr*)&server_sock_addr,sizeof(server_sock_addr)); if(ret < 0) perror("connect error"); else printf("connect ok\n"); /* * getpeername * getsockname struct sockaddr_in peer_sock,client_sock; int len = sizeof(peer_sock); ret = getpeername(fd,(struct sockaddr*)&peer_sock,&len); if(ret == -1) perror("getpeername error"); char addr[16]; printf("peer port = %d\n",peer_sock.sin_port); printf("peer family = %d\n",peer_sock.sin_family); char * result = inet_ntop(AF_INET,&peer_sock.sin_addr,addr,16); if(result == NULL) perror("inet_ntop error"); printf("peer address %s\n",result); len = sizeof(client_sock); ret=getsockname(fd,(struct sockaddr*)&client_sock,&len); if(ret == -1) perror("getsockname error"); printf("client port = %d\n",client_sock.sin_port); printf("client family = %d\n",client_sock.sin_family); printf("client address %s\n",inet_ntop(AF_INET,&client_sock.sin_addr,addr,16)); */ char msg[] = "hellor world"; int n = write(fd,msg,strlen(msg)); printf("send %d byte \n",n); close(fd); return 0;}
FIN 关闭socket fd 则发送一个FIN
RST
SIGPIPE 当一个进程向某个已收到RST的套接字执行写操作时,内核向该进程发送一个SIGPIPE信号,该信号的默认行为是终止进程。
第一次写操作引发RST,第二次写操作引发SIGPIPE
0 0