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)
浙公网安备 33010602011771号