RST_FIN

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值