日期:2014-05-16  浏览次数:20960 次

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 },