有很多方法获取和设置影响套接口的选项:
- getsockopt 和 setsockopt 函数
- fcntl函数 (file control)
- ioctl函数 (io control)
1. getsockopt和setsockopt函数
- level指定系统中解释选项的代码:通用套接口代码,或某个特定于协议的代码
- getsockopt把已获得的选项当前值存放到*optval,其值为0时,表示相应选项被禁止,不为0时表示相应选项被开启。
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
// setsockopt从*optval中取得选项待设置的新值
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t *optlen);
2. 检查所有套接口选项的main函数
int main(int argc, char const *argv[])
{
int fd;
socklen_t len;
struct sock_opts *ptr;
// 遍历sock_opts[]数组中的所有元素
for (ptr = sock_opts; ptr->opt_str != NULL; ptr++)
{
printf("%s\n", ptr->opt_str);
if (ptr->opt_val_str == NULL)
printf("(undefined)\n");
else
{
switch(ptr->opt_level)
{
// 用于测试选项的套接口
case SOL_SOCKET:
case IPPROTO_IP:
case IPPROTO_TCP:
fd = Socket(AF_INET, SOCK_STREAM, 0);
break;
#ifdef IPV6
case IPPROTO_IPV6:
fd = Socket(AF_INET, SOCK_STREAM, 0);
break;
#endif
#ifdef IPPROTO_SCTP
case IPPROTO_SCTP:
fd = Socket(AF_INET, SOCK_STREAM, 0);
break;
#endif
default:
err_quit("Can't create fd for level %d\n", ptr->opt_level);
}
len = sizeof(val);
if (getsockopt(fd, ptr->opt_level, ptr->opt_name, &val, &len) == -1)
{
err_ret("getsockopt error");
} else {
printf("default =%s\n", (*ptr->opt_val_str)(&val, len));
}
close(fd);
}
}
exit(0);
return 0;
}
static char strres[128];
static char * sock_str_flag(union val *ptr, int len)
{
if (len != sizeof(int))
snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
else
snprintf(strres, sizeof(strres), "%s", (ptr->i_val == 0) ? "off" : "on");
return (strres);
}
3. fcntl函数
fcntl(file control)函数可执行各种描述字控制操作。