zoukankan      html  css  js  c++  java
  • linux下getsockopt和setsockopt具体解释及測试

    linux下getsockopt和setsockopt具体解释及測试

    NAME

    名字

           getsockopt, setsockopt - get and set options on sockets

           获取或者设置套接字的选项


    SYNOPSIS

     函数原型

           #include <sys/types.h>          /* See NOTES */
           #include <sys/socket.h>
    
           int getsockopt(int sockfd, int level, int optname,
                          void *optval, socklen_t *optlen);
           int setsockopt(int sockfd, int level, int optname,
                          const void *optval, socklen_t optlen);

    參数:  

    sock:将要被设置或者获取选项的套接字。
    level:选项所在的协议层。
    optname:须要訪问的选项名。


    optval:对于getsockopt(),指向返回选项值的缓冲。

                 对于setsockopt(),指向包括新选项值的缓冲。


    optlen:对于getsockopt(),作为入口參数时,选项值的最大长度。作为出口參数时,选项值的实际长度。

                  对于setsockopt(),The size, in bytes, of the optval buffer. 

    level指定控制套接字的层次.能够取三种值:
         1)SOL_SOCKET:通用套接字选项.
         2)IPPROTO_IP:IP选项.
         3)IPPROTO_TCP:TCP选项. 


    RETURN VALUE

    返回值

           On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.


    错误返回

    ERRORS
           EBADF     The argument sockfd is not a valid descriptor.
    
           EFAULT    The  address  pointed  to  by optval is not in a valid part of the process address space.  For getsockopt(), this error may
                     also be returned if optlen is not in a valid part of the process address space.//
    
           EINVAL    optlen invalid in setsockopt().  In some cases this error can also occur for an invalid value  in  optval  (e.g.,  for  the
                     IP_ADD_MEMBERSHIP option described in ip(7)).
    
           ENOPROTOOPT
                     The option is unknown at the level indicated.
    
           ENOTSOCK  The argument sockfd is a file, not a socket.



    EBADF:sock不是有效的文件描写叙述词
    EFAULT:optval指向的内存并不是有效的进程空间
    EINVAL:在调用setsockopt()时,optlen无效
    ENOPROTOOPT:指定的协议层不能识别选项
    ENOTSOCK:sock描写叙述的不是套接字


    套接字选项和IP层的套接字选项汇总见《unix网络编程第三版卷一》P151图7-1

    以下用一段小代码来检查选项是否受支持并获取默认值:

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

    測试执行结果如图:





    參考:UNIX网络编程卷一

                  Linux Programmer's Manual

  • 相关阅读:
    C语言中条件表达式求最大值和最小值
    面向对象编程:Java的简单数据类型
    JAVA学习经验谈
    JAVA的入门基础一些精典
    面向对象编程:Java复杂数据类型用法
    面向对象编程:Java的简单数据类型
    面向对象编程:Java collection更有效管理elements
    从C++到Java 理解面向对象是关键所在
    JAVA学习经验谈
    JAVA的入门基础一些精典
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4042493.html
Copyright © 2011-2022 走看看