Are socket options inherited across accept() from the listening socket?

后端 未结 4 451
北恋
北恋 2020-12-24 11:46

Suppose the listening socket passed to accept has non-default options set on it with setsockopt. Are these options (some or all of them?) inherited

4条回答
  •  误落风尘
    2020-12-24 12:23

    No, they're not necessarily inherited. Try this sample, which sets the receive buffer size (SO_RCVBUF) on the initial socket to a non-default value and then compares the result with the inherited socket. Run this code, which listens on TCP port 12345, and then connect to it from any other program.

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    void die(const char *f)
    {
      printf("%s: %s\n", f, strerror(errno));
      exit(1);
    }
    
    int main(void)
    {
      int s = socket(AF_INET, SOCK_STREAM, 0);
      if(s < 0)
        die("socket");
    
      int rcvbuf;
      socklen_t optlen = sizeof(rcvbuf);
      if(getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &optlen) < 0)
        die("getsockopt (1)");
      printf("initial rcvbuf: %d\n", rcvbuf);
      rcvbuf *= 2;
      if(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0)
        die("setsockopt");
      printf("set rcvbuf to %d\n", rcvbuf);
    
      struct sockaddr_in sin;
      memset(&sin, 0, sizeof(sin));
      sin.sin_family = AF_INET;
      sin.sin_port = htons(12345);
      sin.sin_addr.s_addr = INADDR_ANY;
      if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
        die("bind");
    
      if(listen(s, 10) < 0)
        die("listen");
    
      struct sockaddr_in client_addr;
      socklen_t addr_len = sizeof(client_addr);
      int s2 = accept(s, (struct sockaddr *)&client_addr, &addr_len);
      if(s2 < 0)
        die("accept");
      printf("accepted connection\n");
      optlen = sizeof(rcvbuf);
      if(getsockopt(s2, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &optlen) < 0)
        die("getsockopt (2)");
    
      printf("new rcvbuf: %d\n", rcvbuf);
    
      return 0;
    }
    

    Result on a machine running Linux 3.0.0-21-generic:

    initial rcvbuf: 87380
    set rcvbuf to 174760
    accepted connection
    new rcvbuf: 262142
    

提交回复
热议问题