008 查看套接字选项是否受支持(获取当前环境下套接字选项默认值)

代码来源:《UNIX网络编程 卷1:套接字联网API》

说明:为以后查看套接字默认值使用

代码:

  1 /* include checkopts1 */
  2 /* *INDENT-OFF* */
  3 
  4 #include <netinet/tcp.h>        /* for TCP_xxx defines */
  5 #include <stdio.h>
  6 #include <string.h>
  7 #include <stdlib.h>
  8 #include <fcntl.h>
  9 #include <sys/types.h>
 10 #include <sys/socket.h>
 11 #include <arpa/inet.h>
 12 #include <unistd.h>
 13 #include <signal.h>
 14 #include <sys/time.h>
 15 #include <time.h>
 16 #include <sys/epoll.h>
 17 
 18 union val {
 19   int                i_val;
 20   long                l_val;
 21   struct linger        linger_val;
 22   struct timeval    timeval_val;
 23 } val;
 24 
 25 static char    *sock_str_flag(union val *, int);
 26 static char    *sock_str_int(union val *, int);
 27 static char    *sock_str_linger(union val *, int);
 28 static char    *sock_str_timeval(union val *, int);
 29 
 30 struct sock_opts {
 31   const char       *opt_str;
 32   int        opt_level;
 33   int        opt_name;
 34   char   *(*opt_val_str)(union val *, int);
 35 } sock_opts[] = {
 36     { "SO_BROADCAST",        SOL_SOCKET,    SO_BROADCAST,    sock_str_flag },
 37     { "SO_DEBUG",            SOL_SOCKET,    SO_DEBUG,        sock_str_flag },
 38     { "SO_DONTROUTE",        SOL_SOCKET,    SO_DONTROUTE,    sock_str_flag },
 39     { "SO_ERROR",            SOL_SOCKET,    SO_ERROR,        sock_str_int },
 40     { "SO_KEEPALIVE",        SOL_SOCKET,    SO_KEEPALIVE,    sock_str_flag },
 41     { "SO_LINGER",            SOL_SOCKET,    SO_LINGER,        sock_str_linger },
 42     { "SO_OOBINLINE",        SOL_SOCKET,    SO_OOBINLINE,    sock_str_flag },
 43     { "SO_RCVBUF",            SOL_SOCKET,    SO_RCVBUF,        sock_str_int },
 44     { "SO_SNDBUF",            SOL_SOCKET,    SO_SNDBUF,        sock_str_int },
 45     { "SO_RCVLOWAT",        SOL_SOCKET,    SO_RCVLOWAT,    sock_str_int },
 46     { "SO_SNDLOWAT",        SOL_SOCKET,    SO_SNDLOWAT,    sock_str_int },
 47     { "SO_RCVTIMEO",        SOL_SOCKET,    SO_RCVTIMEO,    sock_str_timeval },
 48     { "SO_SNDTIMEO",        SOL_SOCKET,    SO_SNDTIMEO,    sock_str_timeval },
 49     { "SO_REUSEADDR",        SOL_SOCKET,    SO_REUSEADDR,    sock_str_flag },
 50 #ifdef    SO_REUSEPORT
 51     { "SO_REUSEPORT",        SOL_SOCKET,    SO_REUSEPORT,    sock_str_flag },
 52 #else
 53     { "SO_REUSEPORT",        0,            0,                NULL },
 54 #endif
 55     { "SO_TYPE",            SOL_SOCKET,    SO_TYPE,        sock_str_int },
 56     //{ "SO_USELOOPBACK",        SOL_SOCKET,    SO_USELOOPBACK,    sock_str_flag },
 57     { "IP_TOS",                IPPROTO_IP,    IP_TOS,            sock_str_int },
 58     { "IP_TTL",                IPPROTO_IP,    IP_TTL,            sock_str_int },
 59 #ifdef    IPV6_DONTFRAG
 60     { "IPV6_DONTFRAG",        IPPROTO_IPV6,IPV6_DONTFRAG,    sock_str_flag },
 61 #else
 62     { "IPV6_DONTFRAG",        0,            0,                NULL },
 63 #endif
 64 #ifdef    IPV6_UNICAST_HOPS
 65     { "IPV6_UNICAST_HOPS",    IPPROTO_IPV6,IPV6_UNICAST_HOPS,sock_str_int },
 66 #else
 67     { "IPV6_UNICAST_HOPS",    0,            0,                NULL },
 68 #endif
 69 #ifdef    IPV6_V6ONLY
 70     { "IPV6_V6ONLY",        IPPROTO_IPV6,IPV6_V6ONLY,    sock_str_flag },
 71 #else
 72     { "IPV6_V6ONLY",        0,            0,                NULL },
 73 #endif
 74     { "TCP_MAXSEG",            IPPROTO_TCP,TCP_MAXSEG,        sock_str_int },
 75     { "TCP_NODELAY",        IPPROTO_TCP,TCP_NODELAY,    sock_str_flag },
 76 #ifdef    SCTP_AUTOCLOSE
 77     { "SCTP_AUTOCLOSE",        IPPROTO_SCTP,SCTP_AUTOCLOSE,sock_str_int },
 78 #else
 79     { "SCTP_AUTOCLOSE",        0,            0,                NULL },
 80 #endif
 81 #ifdef    SCTP_MAXBURST
 82     { "SCTP_MAXBURST",        IPPROTO_SCTP,SCTP_MAXBURST,    sock_str_int },
 83 #else
 84     { "SCTP_MAXBURST",        0,            0,                NULL },
 85 #endif
 86 #ifdef    SCTP_MAXSEG
 87     { "SCTP_MAXSEG",        IPPROTO_SCTP,SCTP_MAXSEG,    sock_str_int },
 88 #else
 89     { "SCTP_MAXSEG",        0,            0,                NULL },
 90 #endif
 91 #ifdef    SCTP_NODELAY
 92     { "SCTP_NODELAY",        IPPROTO_SCTP,SCTP_NODELAY,    sock_str_flag },
 93 #else
 94     { "SCTP_NODELAY",        0,            0,                NULL },
 95 #endif
 96     { NULL,                    0,            0,                NULL }
 97 };
 98 /* *INDENT-ON* */
 99 /* end checkopts1 */
100 
101 /* include checkopts2 */
102 int
103 main(int argc, char **argv)
104 {
105     int                    fd;
106     socklen_t            len;
107     struct sock_opts    *ptr;
108 
109     for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
110         printf("%s: ", ptr->opt_str);
111         if (ptr->opt_val_str == NULL)
112             printf("(undefined)\n");
113         else {
114             switch(ptr->opt_level) {
115             case SOL_SOCKET:
116             case IPPROTO_IP:
117             case IPPROTO_TCP:
118                 fd = socket(AF_INET, SOCK_STREAM, 0);
119                 break;
120 #ifdef    IPV6
121             case IPPROTO_IPV6:
122                 fd = Socket(AF_INET6, SOCK_STREAM, 0);
123                 break;
124 #endif
125 #ifdef    IPPROTO_SCTP
126             case IPPROTO_SCTP:
127                 fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
128                 break;
129 #endif
130             default:
131                 printf("Can't create fd for level %d\n", ptr->opt_level);
132             }
133 
134             len = sizeof(val);
135             if (getsockopt(fd, ptr->opt_level, ptr->opt_name, &val, &len) == -1) {
136                 printf("getsockopt error\n");
137             } else {
138                 printf("default = %s\n", (*ptr->opt_val_str)(&val, len));
139             }
140             close(fd);
141         }
142     }
143     exit(0);
144 }
145 /* end checkopts2 */
146 
147 /* include checkopts3 */
148 static char    strres[128];
149 
150 static char    *sock_str_flag(union val *ptr, int len)
151 {
152 /* *INDENT-OFF* */
153     if (len != sizeof(int))
154         snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
155     else
156         snprintf(strres, sizeof(strres),
157                  "%s", (ptr->i_val == 0) ? "off" : "on");
158     return(strres);
159 /* *INDENT-ON* */
160 }
161 /* end checkopts3 */
162 
163 static char    *sock_str_int(union val *ptr, int len)
164 {
165     if (len != sizeof(int))
166         snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
167     else
168         snprintf(strres, sizeof(strres), "%d", ptr->i_val);
169     return(strres);
170 }
171 
172 static char    *sock_str_linger(union val *ptr, int len)
173 {
174     struct linger    *lptr = &ptr->linger_val;
175 
176     if (len != sizeof(struct linger))
177         snprintf(strres, sizeof(strres),
178                  "size (%d) not sizeof(struct linger)", len);
179     else
180         snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d",
181                  lptr->l_onoff, lptr->l_linger);
182     return(strres);
183 }
184 
185 static char    *sock_str_timeval(union val *ptr, int len)
186 {
187     struct timeval    *tvptr = &ptr->timeval_val;
188 
189     if (len != sizeof(struct timeval))
190         snprintf(strres, sizeof(strres),
191                  "size (%d) not sizeof(struct timeval)", len);
192     else
193         snprintf(strres, sizeof(strres), "%d sec, %d usec", (int )tvptr->tv_sec, (int )tvptr->tv_usec);
194     return(strres);
195 }

运行结果

 

SO_BROADCAST: default = off
SO_DEBUG: default = off
SO_DONTROUTE: default = off
SO_ERROR: default = 0
SO_KEEPALIVE: default = off
SO_LINGER: default = l_onoff = 0, l_linger = 0
SO_OOBINLINE: default = off
SO_RCVBUF: default = 87380       //接受缓冲区大小
SO_SNDBUF: default = 16384       //发送缓冲区大小
SO_RCVLOWAT: default = 1
SO_SNDLOWAT: default = 1
SO_RCVTIMEO: default = 0 sec, 0 usec
SO_SNDTIMEO: default = 0 sec, 0 usec
SO_REUSEADDR: default = off
SO_REUSEPORT: default = off
SO_TYPE: default = 1          //套接字类型
IP_TOS: default = 0
IP_TTL: default = 64          //存活时间
IPV6_DONTFRAG: (undefined)
IPV6_UNICAST_HOPS: Can't create fd for level 41
getsockopt error
IPV6_V6ONLY: Can't create fd for level 41
getsockopt error
TCP_MAXSEG: default = 536
TCP_NODELAY: default = off
SCTP_AUTOCLOSE: (undefined)
SCTP_MAXBURST: (undefined)
SCTP_MAXSEG: (undefined)
SCTP_NODELAY: (undefined)

 

posted @ 2015-12-02 18:06  ruo_yu  阅读(359)  评论(0)    收藏  举报