导航

关于连接释放的信号

如果没有要读的数据,但调用read,返回值为-1,errno为11,即EAGAIN

https://baike.baidu.com/item/errno/11040395?fr=aladdin

---------------------------------

经验证,当client调用close,此时server进行read,n为0

---------------------

测试程序代码

//server.c

#include <sys/socket.h>
/* socket */
#include <netinet/in.h>
/* struct sockaddr_in */
#include <unistd.h>
/* read,close,write */
#include <arpa/inet.h>
/* inet_addr */
#include <fcntl.h>
/* fcntl */

void main(void)
{
    struct sockaddr_in addr;
    struct sockaddr *paddr = (struct sockaddr *)&addr;

    addr.sin_family = AF_INET;
    addr.sin_port = xxxx;
    addr.sin_addr.s_addr = inet_addr("a.b.c.d");
    int mstrfd = socket(AF_INET, SOCK_STREAM, 0);

    bind(mstrfd, paddr, sizeof(struct sockaddr));

    listen(mstrfd, 5);

    struct sockaddr clntAddr;
    int size = sizeof(struct sockaddr_in);

    int servfd = accept(mstrfd, &clntAddr, &size);

    char p[100];

    int flags = fcntl(servfd, F_GETFL);

    flags |= O_NONBLOCK;

    fcntl(servfd, F_SETFL, flags);

    int n = read(servfd, p, 100);

        n = read(servfd, p, 100);    

    close(servfd);
}


//client.c

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>

void main(void)
{
    struct sockaddr_in addr;
    struct sockaddr *paddr = (struct sockaddr *)&addr;

    addr.sin_family = AF_INET;
    addr.sin_port = xxxx;
    addr.sin_addr.s_addr = inet_addr("a.b.c.d");
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    connect(fd, paddr, sizeof(struct sockaddr));

    char p[] = "Hello, this is client";
    int n = write(fd, p, strlen(p));

    close(fd);
}

 

--------------------

Linux/UNIX系统编程手册下

61.3 专用于套接字的I/O系统调用

recv可以设置MSG_DONTWAIT

也可以通过tcntl设置O_NONBLOCK

即44.9 非阻塞I/O

int flags = fcntl(fd, F_GETFL);

flags |= O_NONBLOCK;

fcntl(fd, F_SETFL, flags);

区别在于,每次调用recv的时候,你都可以设置此次接收的模式,fcntl是一直有效的

posted on 2021-05-18 14:16  toughcactus  阅读(43)  评论(0编辑  收藏  举报