zoukankan      html  css  js  c++  java
  • 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
    ***********************************/
  • 相关阅读:
    POJ 2251 Dungeon Master
    HDU 3085 Nightmare Ⅱ
    CodeForces 1060 B Maximum Sum of Digits
    HDU 1166 敌兵布阵(树状数组)
    HDOJ 2050 折线分割平面
    HDU 5879 Cure
    HDU 1878 欧拉回路
    HDU 6225 Little Boxes
    ZOJ 2971 Give Me the Number
    HDU 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/cfox/p/2984610.html
Copyright © 2011-2022 走看看