• socket


    在做一个简单的socket程序时,遇到当client退出时,server状态为defunct情况。过程如下:

     (1)   Server  <--  Client

     (2)   Server (accept) <-X- Client
                       (fork)             |
                 New Server  <-----+

     (3)   Server            杀掉Client后
            New Server <defunct>

    原因:在子进程退出时,发送了SIGCHLD信号。

    解决方法在父进程中waitpid(); 可以获得子进程的退出状态

    
    
    void sig_chld (int signo) {
        pid_t pid;
        int stat;
    
        while ((pid = waitpid(-1,&stat, WNOHANG)) > 0)
            printf("child %d terminated\n",pid);
        return;
    }

    int main()
    {
    signal(SIGCHLD, sig_chld);
    //...
    fork();
    }

     也可以在父进程中忽略该信号

    signal(SIGCHLD,SIG_IGN); 

    下面是几个socket用到的属性介绍. 

    int socket(int domain, int type, int protocol);
    
    /* int type SOCK_CLOEXEC: 这个属性对应open函数的O_CLOEXEC 该标志作用为,当执行fork并执行exec的时候,在子进程中,自动关闭此描述符
    参考:http://blog.csdn.net/chrisniu1984/article/details/7050663
    */ /* 也可以通过如下代码设置 */
    int v;
    v
    = fcntl(fd, F_GETFD, 0);
    fcntl(fd, F_SETFD, v
    |FD_CLOEXEC);


    /* SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组还是唯一确定的。
    * 所以,重启后的服务程序有可能收到非期望数据。必须慎重使用 SO_REUSEADDR 选项。
    * 如果你的服务程序停止后想立即重启,而新套接字依旧使用同一地址和端口,此时 SO_REUSEADDR 选项非常有用。
    */

    setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));


    /* fcntl(fd, F_SETFL, O_NONBLOCK);
    * 如果socket设置了如上属性,那么accept也将是非阻塞的。accept()函数会立即返回。
    * 注:没有数据时,会返回错误。
    */

    accept(s->fd, (struct sockaddr*)&cliaddr, &clilen);

    read 收包,判断是否一个接收已经完成了。

    /* 文件,socket 同理,read返回0时,才表示文件尾/数据包尾 */
    while(read(sock, buf, sizeof(buf)-1))
    {
      //数据放入缓冲区
    }
    /***********************************
    同时有如下内部逻辑
    TCP协议是面向流的,read和write调用的返回值往往小于参数指定的字节数。对于read调用,
    如果接收缓冲区中有20字节,请求读100个字节,就会返回20。对于write调用,如果请求写100个字节,
    而发送缓冲区中只有20个字节的空闲位置,那么write会阻塞,直到把100个字节全部交给发送缓冲区才返回,
    但如果socket文件描述符有O_NONBLOCK标志,则write不阻塞,直接返回20
    ***********************************/
  • 相关阅读:
    Prim算法以及Kruskal算法
    PAT甲级考前整理(2019年3月备考)之三,持续更新中.....
    PAT甲级考前整理(2019年3月备考)之一
    PAT甲级考前整理(2019年3月备考)之二,持续更新中.....
    linux下挂载U盘
    opencv2已有的情况下,安装opencv3以及对应的opencv_contrib
    二维数组和二级指针做函数参数的问题
    ubuntu14.04下 python2.7怎么链接到安装在指定文件夹的opencv3
    使用opencv的nonfree模块
    PaddlePaddle开源平台的应用
  • 原文地址:https://www.cnblogs.com/cfox/p/2984610.html
Copyright © 2020-2023  润新知