网络编程学习笔记(getsockopt和setsockopt函数)

其原型为:

#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);

成功返回0, 失败返回-1

其代码如下:

#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <netinet/tcp.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>

union val
{
	int i_val;
	long l_val;
	char c_val[10];
	struct linger linger_val;
	struct timeval timeval_val;
}val;

static char *sock_str_flag(union val*, int);
static char *sock_str_int(union val*, int);
static char *sock_str_linger(union val*, int);
static char *sock_str_timeval(union val*, int);

struct sock_opts
{
	char *opt_str;
	int opt_level;
	int opt_name;
	char *(*opt_val_str)(union val*, int);	
}sock_opts[] = {
		"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag,
		"SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag,
		"SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag,
		"SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int,
		"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag,
		"SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger,
		"SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag,
		"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int,
		"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int,
		"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int, 
		"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int,
		"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval,
		"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval,
		"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag,
		#ifdef SO_REUSEPORT
		"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag,
		#else
		"SO_REUSEPROT", 0, 0, NULL,
		#endif
		"SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int,
		//"SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag,
		"IP_TOS", IPPROTO_IP, IP_TOS, sock_str_int,
		"IP_TTL", IPPROTO_IP, IP_TTL, sock_str_int,
		"TCP_MAXSEG", IPPROTO_TCP, TCP_MAXSEG, sock_str_int,
		"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, sock_str_flag,
		NULL, 0, 0, NULL
		};

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

static char *sock_str_int(union val* ptr, int len)
{
	if (len != sizeof(int)) {
		snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
	} else {
		snprintf(strres, sizeof(strres), "%d", ptr->i_val);
	}	

	return strres;
}

static char *sock_str_linger(union val* ptr, int len)
{
	if (len != sizeof(struct linger)) {
		snprintf(strres, sizeof(strres), "size (%d) not sizeof(struct linger)", len);
	} else {
		snprintf(strres, sizeof(strres), "l_onoff=%d, l_linger=%d", ptr->linger_val.l_onoff, ptr->linger_val.l_linger);
	}

	return strres;
}


static char *sock_str_timeval(union val* ptr, int len)
{
	if (len != sizeof(struct timeval)) {
		snprintf(strres, sizeof(strres), "size (%d) not sizeof(struct timeval)", len);
	} else {
		snprintf(strres, sizeof(strres), "tv_sec=%d, tv_usec=%d", ptr->timeval_val.tv_sec, ptr->timeval_val.tv_usec);
	}

	return strres;
}

int main(int argc, char **argv)
{
	int fd, len;
	struct sock_opts *ptr;
	
	fd = socket(AF_INET, SOCK_STREAM, 0);	
	
	for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
		printf("%s:", ptr->opt_str);
		if (ptr->opt_val_str == NULL) {
			printf("undefined\n");
		} else {
			len = sizeof(val);
			if (getsockopt(fd, ptr->opt_level, ptr->opt_name, &val, &len) == -1) {
				printf("error:%s\n", strerror(errno));
				return -1;
			} else {
				printf("default: %s\n", ptr->opt_val_str(&val, len));
			}
		}
	}
	return 0;
}	
	


SO_USELOOPBACK竟然找不到定义

运行后输出截图如下:



套接口的选项:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: getsockopt/setsockopt函数是用于设置和获取套接字选项的函数。其中,getsockopt用于获取指定套接字选项的值,而setsockopt用于设置指定套接字选项的值。这两个函数网络编程中经常被用到。 ### 回答2: getsockoptsetsockopt函数是用来获取和设置套接字选项的API函数,在网络编程中十分常见。套接字选项是一个可选的参数,它允许用户设置套接字的某些属性,例如超时时间、是否启用广播、缓冲区大小等等。 getsockopt函数用于获取套接字选项的当前值。它需要传入以下参数: 1. sockfd: 套接字描述符; 2. level: 选项定义的协议层; 3. optname: 需要获取的选项名称; 4. optval: 指向一个缓冲区,用于存储获取到的选项值; 5. optlen: 缓冲区的大小。 setsockopt函数用于设置套接字选项的值。它需要传入以下参数: 1. sockfd: 套接字描述符; 2. level: 选项定义的协议层; 3. optname: 需要设置的选项名称; 4. optval: 指向一个缓冲区,用于存储需要设置的选项值; 5. optlen: 缓冲区的大小。 需要注意的是,不同的协议层和选项名称对应的值有所不同。可以通过man手册或者网络查找相关资料来获取更详细的信息。 这些函数网络编程中经常被使用,例如可以通过setsockopt函数设置套接字的超时时间,当网络I/O操作超过指定时间时,会自动返回一个超时错误;也可以通过getsockopt函数来获取当前是否启用了广播选项等等。 总之,getsockoptsetsockopt函数可以让我们更方便地控制和监控套接字的行为,提高网络通信的效率和可靠性。 ### 回答3: getsockoptsetsockopt函数都是与网络编程相关的系统调用函数,它们用于控制和获取套接字选项。在进行网络编程时,我们需要使用这两个函数来调整套接字的设置,以便实现更好的网络通信效果。 具体地说,setsockopt函数可以设置某个套接字的选项值,例如设置套接字的发送和接收缓冲区大小、设置是否对数据包进行分片等等。而getsockopt函数则可以获取某个套接字的选项值,以便进行校验或者输出日志等功能。 关于参数方面,getsockoptsetsockopt函数都需要传入当前操作的套接字句柄,以及要设置或者获取的选项值。setsockopt函数还需要传入对应选项值的指针和大小;而getsockopt函数需要传入一个指向缓冲区的指针,用来接收获取的选项值和大小。 需要注意的是,每个选项都有对应的协议层级,而不同的选项可能只在特定协议的套接字上有效。因此,在使用这两个函数时,需要注意选项的协议层级,以及操作的套接字所使用的协议类型,避免出现无法设置或获取选项值的情况。 同时,getsockoptsetsockopt函数也有一定的返回值,setsockopt函数返回是否设置成功,而getsockopt函数返回获取的选项值的长度。在使用时,我们需要对返回值进行判断,以便及时发现并解决问题。 总之,getsockoptsetsockopt函数网络编程中必不可少的函数。它们用于设置和获取套接字的选项值,以便我们能够更加精细地控制网络通信的行为,从而提高网络通信效率和质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值