Unix网络编程代码 第7章 套接字选项

本文介绍了一种检测套接字选项是否受支持的方法,并获取其默认值。通过编写C语言程序,针对不同的套接字级别(如SOL_SOCKET、IPPROTO_IP等),实现了对多种常见套接字选项的支持情况及默认配置进行查询。

第7章 套接字选项

7.3 检查选项是否受支持并获取默认值


#define __need_timeval
#include	<stdio.h>
#include	<time.h>
#include	<netinet/tcp.h>	/* for TCP_xxx defines */
#include	<sys/socket.h>
#include	<netinet/in.h>	/* sockaddr_in{} and other Internet defns */
#include	<string.h>
#include	<stdlib.h>
#include	<errno.h>
#include	<syslog.h>	/* for syslog() */
#include	<stdarg.h>	/* ANSI C header file */
#include	<unistd.h>
#define	MAXLINE		4096	/* max text line length */
int daemon_proc;		/* set nonzero by daemon_init() */
union val {
	int i_val;
	long l_val;
	struct linger linger_val;
	struct timeval timeval_val;
} val;

static char strres[128];
char *sock_str_flag(union val *ptr, int len)
{
		/* *INDENT-OFF* */
		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);
					/* *INDENT-ON* */
}

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

char *sock_str_linger(union val *ptr, int len)
{
	struct linger *lptr = &ptr->linger_val;

	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",
			 lptr->l_onoff, lptr->l_linger);
	return (strres);
}

char *sock_str_timeval(union val *ptr, int len)
{
	struct timeval *tvptr = &ptr->timeval_val;

	if (len != sizeof(struct timeval))
		snprintf(strres, sizeof(strres),
			 "size (%d) not sizeof(struct timeval)", len);
	else
		snprintf(strres, sizeof(strres), "%ld sec, %ld usec",
			 tvptr->tv_sec, tvptr->tv_usec);
	return (strres);
}

struct sock_opts {
	const 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_REUSEPORT", 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},
#ifdef IPV6
#ifdef	IPV6_DONTFRAG
	{
	"IPV6_DONTFRAG", IPPROTO_IPV6, IPV6_DONTFRAG, sock_str_flag},
#else
	{
	"IPV6_DONTFRAG", 0, 0, NULL},
#endif
#ifdef	IPV6_UNICAST_HOPS
	{
	"IPV6_UNICAST_HOPS", IPPROTO_IPV6, IPV6_UNICAST_HOPS,
		    sock_str_int},
#else
	{
	"IPV6_UNICAST_HOPS", 0, 0, NULL},
#endif
#ifdef	IPV6_V6ONLY
	{
	"IPV6_V6ONLY", IPPROTO_IPV6, IPV6_V6ONLY, sock_str_flag},
#else
	{
	"IPV6_V6ONLY", 0, 0, NULL},
#endif
#endif
	{
	"TCP_MAXSEG", IPPROTO_TCP, TCP_MAXSEG, sock_str_int}, {
	"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, sock_str_flag},
#ifdef	SCTP_AUTOCLOSE
	{
	"SCTP_AUTOCLOSE", IPPROTO_SCTP, SCTP_AUTOCLOSE, sock_str_int},
#else
	{
	"SCTP_AUTOCLOSE", 0, 0, NULL},
#endif
#ifdef	SCTP_MAXBURST
	{
	"SCTP_MAXBURST", IPPROTO_SCTP, SCTP_MAXBURST, sock_str_int},
#else
	{
	"SCTP_MAXBURST", 0, 0, NULL},
#endif
#ifdef	SCTP_MAXSEG
	{
	"SCTP_MAXSEG", IPPROTO_SCTP, SCTP_MAXSEG, sock_str_int},
#else
	{
	"SCTP_MAXSEG", 0, 0, NULL},
#endif
#ifdef	SCTP_NODELAY
	{
	"SCTP_NODELAY", IPPROTO_SCTP, SCTP_NODELAY, sock_str_flag},
#else
	{
	"SCTP_NODELAY", 0, 0, NULL},
#endif
	{
	NULL, 0, 0, NULL}
};

/* *INDENT-ON* */
void err_doit(int errnoflag, int level, const char *fmt, va_list ap)
{
	int errno_save, n;
	char buf[MAXLINE + 1];

	errno_save = errno;	/* value caller might want printed */
#ifdef	HAVE_VSNPRINTF
	vsnprintf(buf, MAXLINE, fmt, ap);	/* safe */
#else
	vsprintf(buf, fmt, ap);	/* not safe */
#endif
	n = strlen(buf);
	if (errnoflag)
		snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
	strcat(buf, "\n");

	if (daemon_proc) {
		syslog(level, "%s", buf);
	} else {
		fflush(stdout);	/* in case stdout and stderr are the same */
		fputs(buf, stderr);
		fflush(stderr);
	}
	return;
}

void err_quit(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	err_doit(0, LOG_ERR, fmt, ap);
	va_end(ap);
	exit(1);
}

void err_sys(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	err_doit(1, LOG_ERR, fmt, ap);
	va_end(ap);
	exit(1);
}

void err_ret(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	err_doit(1, LOG_INFO, fmt, ap);
	va_end(ap);
	return;
}

int Socket(int family, int type, int protocol)
{
	int n;

	if ((n = socket(family, type, protocol)) < 0)
		err_sys("socket error");
	return (n);
}

int main()
{
	int fd;
	socklen_t len;
	struct sock_opts *ptr;

	for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
		printf("%s: ", 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_INET6, SOCK_STREAM, 0);
				break;
#endif
#ifdef	IPPROTO_SCTP
			case IPPROTO_SCTP:
				fd = Socket(AF_INET, SOCK_SEQPACKET,
					    IPPROTO_SCTP);
				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);
}

内容概要:本文介绍了一个关于超声谐波成像中幅度调制聚焦超声所引起全场位移和应变的分析模型,并提供了基于Matlab的代码实现。该模型旨在精确模拟和分析在超声谐波成像过程中,由于幅度调制聚焦超声作用于生物组织时产生的力学效应,包括全场的位移与应变分布,从而为医学成像和治疗提供理论支持和技术超声谐波成像中幅度调制聚焦超声引起的全场位移和应变的分析模型(Matlab代码实现)手段。文中详细阐述了模型构建的物理基础、数学推导过程以及Matlab仿真流程,具有较强的理论深度与工程应用价值。; 适合人群:具备一定声学、生物医学工程或力学背景,熟悉Matlab编程,从事医学成像、超声技术或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于超声弹性成像中的力学建模与仿真分析;②支持高强度聚焦超声(HIFU)治疗中的组织响应预测;③作为教学案例帮助理解超声与组织相互作用的物理机制;④为相关科研项目提供可复用的Matlab代码框架。; 阅读建议:建议读者结合超声物理和连续介质力学基础知识进行学习,重点关注模型假设、偏微分方程的数值求解方法及Matlab实现细节,建议动手运行并修改代码以加深理解,同时可拓展应用于其他超声成像或治疗场景的仿真研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值