我是靠谱客的博主 专一金针菇,最近开发中收集的这篇文章主要介绍linux下getsockopt和setsockopt详解及测试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)n");
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 %dn", 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 = %sn", (*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

最后

以上就是专一金针菇为你收集整理的linux下getsockopt和setsockopt详解及测试linux下getsockopt和setsockopt详解及测试 的全部内容,希望文章能够帮你解决linux下getsockopt和setsockopt详解及测试linux下getsockopt和setsockopt详解及测试 所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部