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
原创粉丝点击