⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockopts.c

📁 基于unix(solrais)的socket 原始代码编程。C/C++语言。SOCKET VER/BSD
💻 C
字号:
/* * Copyright (c) 1993 W. Richard Stevens.  All rights reserved. * Permission to use or modify this software and its documentation only for * educational purposes and without fee is hereby granted, provided that * the above copyright notice appear in all copies.  The author makes no * representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. */#include	"sock.h"#include	<fcntl.h>#include	<sys/ioctl.h>voidsockopts(int sockfd, int doall){    int 			option, optlen;	struct linger	ling;	struct timeval	timer;	/* "doall" is 0 for a server's listening socket (i.e., before	   accept() has returned.)  Some socket options such as SO_KEEPALIVE	   don't make sense at this point, while others like SO_DEBUG do. */    if (debug) {        option = 1;        if (setsockopt(sockfd, SOL_SOCKET, SO_DEBUG,										&option, sizeof(option)) < 0)            err_sys("SO_DEBUG setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, SOL_SOCKET, SO_DEBUG,										&option, &optlen) < 0)            err_sys("SO_DEBUG getsockopt error");		if (option == 0)			err_quit("SO_DEBUG not set (%d)", option);		if (verbose)			fprintf(stderr, "SO_DEBUG set\n");    }    if (dontroute) {        option = 1;        if (setsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE,										&option, sizeof(option)) < 0)            err_sys("SO_DONTROUTE setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE,										&option, &optlen) < 0)            err_sys("SO_DONTROUTE getsockopt error");		if (option == 0)			err_quit("SO_DONTROUTE not set (%d)", option);		if (verbose)			fprintf(stderr, "SO_DONTROUTE set\n");    }#ifdef	IP_TOS    if (iptos != -1 && doall == 0) {        if (setsockopt(sockfd, IPPROTO_IP, IP_TOS,										&iptos, sizeof(iptos)) < 0)            err_sys("IP_TOS setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, IPPROTO_IP, IP_TOS,										&option, &optlen) < 0)            err_sys("IP_TOS getsockopt error");		if (option != iptos)			err_quit("IP_TOS not set (%d)", option);		if (verbose)			fprintf(stderr, "IP_TOS set to %d\n", iptos);    }#endif#ifdef	IP_TTL    if (ipttl != -1 && doall == 0) {        if (setsockopt(sockfd, IPPROTO_IP, IP_TTL,										&ipttl, sizeof(ipttl)) < 0)            err_sys("IP_TTL setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, IPPROTO_IP, IP_TTL,										&option, &optlen) < 0)            err_sys("IP_TTL getsockopt error");		if (option != ipttl)			err_quit("IP_TTL not set (%d)", option);		if (verbose)			fprintf(stderr, "IP_TTL set to %d\n", ipttl);    }#endif    if (maxseg && udp == 0) {			/* Need to set MSS for server before connection established */			/* Beware: some kernels do not let the process set this socket			   option; others only let it be decreased. */        if (setsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,										&maxseg, sizeof(maxseg)) < 0)            err_sys("TCP_MAXSEG setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,										&option, &optlen) < 0)            err_sys("TCP_MAXSEG getsockopt error");		if (verbose)			fprintf(stderr, "TCP_MAXSEG = %d\n", option);    }	if (sroute_cnt > 0)		sroute_set(sockfd);    if (broadcast) {        option = 1;        if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,										&option, sizeof(option)) < 0)            err_sys("SO_BROADCAST setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,										&option, &optlen) < 0)            err_sys("SO_BROADCAST getsockopt error");		if (option == 0)			err_quit("SO_BROADCAST not set (%d)", option);		if (verbose)			fprintf(stderr, "SO_BROADCAST set\n");#ifdef	IP_ONESBCAST		if (onesbcast) {	        option = 1;	        if (setsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST,											&option, sizeof(option)) < 0)	            err_sys("IP_ONESBCAST setsockopt error");		        option = 0;			optlen = sizeof(option);	        if (getsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST,											&option, &optlen) < 0)	            err_sys("IP_ONESBCAST getsockopt error");			if (option == 0)				err_quit("IP_ONESBCAST not set (%d)", option);				if (verbose)				fprintf(stderr, "IP_ONESBCAST set\n");		}#endif    }#ifdef	IP_ADD_MEMBERSHIP    if (joinip[0]) {		struct ip_mreq	join;		if (inet_aton(joinip, &join.imr_multiaddr) == 0)			err_quit("invalid multicast address: %s", joinip);		join.imr_interface.s_addr = htonl(INADDR_ANY);        if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,										&join, sizeof(join)) < 0)            err_sys("IP_ADD_MEMBERSHIP setsockopt error");		if (verbose)			fprintf(stderr, "IP_ADD_MEMBERSHIP set\n");    }#endif#ifdef	IP_MULTICAST_TTL    if (mcastttl) {		u_char	ttl = mcastttl;        if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,										&ttl, sizeof(ttl)) < 0)            err_sys("IP_MULTICAST_TTL setsockopt error");		optlen = sizeof(ttl);        if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,										&ttl, &optlen) < 0)            err_sys("IP_MULTICAST_TTL getsockopt error");		if (ttl != mcastttl)			err_quit("IP_MULTICAST_TTL not set (%d)", ttl);		if (verbose)			fprintf(stderr, "IP_MULTICAST_TTL set to %d\n", ttl);    }#endif    if (keepalive && doall && udp == 0) {        option = 1;        if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,										&option, sizeof(option)) < 0)            err_sys("SO_KEEPALIVE setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,										&option, &optlen) < 0)            err_sys("SO_KEEPALIVE getsockopt error");		if (option == 0)			err_quit("SO_KEEPALIVE not set (%d)", option);		if (verbose)			fprintf(stderr, "SO_KEEPALIVE set\n");    }    if (nodelay && doall && udp == 0) {        option = 1;        if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,										&option, sizeof(option)) < 0)            err_sys("TCP_NODELAY setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,										&option, &optlen) < 0)            err_sys("TCP_NODELAY getsockopt error");		if (option == 0)			err_quit("TCP_NODELAY not set (%d)", option);		if (verbose)			fprintf(stderr, "TCP_NODELAY set\n");    }    if (doall && verbose && udp == 0) {	/* just print MSS if verbose */        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,										&option, &optlen) < 0)            err_sys("TCP_MAXSEG getsockopt error");		fprintf(stderr, "TCP_MAXSEG = %d\n", option);    }    if (linger >= 0 && doall && udp == 0) {        ling.l_onoff = 1;        ling.l_linger = linger;		/* 0 for abortive disconnect */        if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER,										&ling, sizeof(ling)) < 0)            err_sys("SO_LINGER setsockopt error");		ling.l_onoff = 0;		ling.l_linger = -1;        optlen = sizeof(struct linger);        if (getsockopt(sockfd, SOL_SOCKET, SO_LINGER,										&ling, &optlen) < 0)            err_sys("SO_LINGER getsockopt error");		if (ling.l_onoff == 0 || ling.l_linger != linger)			err_quit("SO_LINGER not set (%d, %d)", ling.l_onoff, ling.l_linger);        if (verbose)            fprintf(stderr, "linger %s, time = %d\n",                            ling.l_onoff ? "on" : "off", ling.l_linger);    }    if (doall && rcvtimeo) {#ifdef	SO_RCVTIMEO		/* User specifies millisec, must convert to sec/usec */		timer.tv_sec  =  rcvtimeo / 1000;		timer.tv_usec = (rcvtimeo % 1000) * 1000;        if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,										&timer, sizeof(timer)) < 0)            err_sys("SO_RCVTIMEO setsockopt error");		timer.tv_sec = timer.tv_usec = 0;		optlen = sizeof(timer);        if (getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,										&timer, &optlen) < 0)            err_sys("SO_RCVTIMEO getsockopt error");		if (verbose)			fprintf(stderr, "SO_RCVTIMEO: %ld.%06ld\n",									timer.tv_sec, timer.tv_usec);#else		fprintf(stderr, "warning: SO_RCVTIMEO not supported by host\n");#endif    }    if (doall && sndtimeo) {#ifdef	SO_SNDTIMEO		/* User specifies millisec, must convert to sec/usec */		timer.tv_sec  =  sndtimeo / 1000;		timer.tv_usec = (sndtimeo % 1000) * 1000;        if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO,										&timer, sizeof(timer)) < 0)            err_sys("SO_SNDTIMEO setsockopt error");		timer.tv_sec = timer.tv_usec = 0;		optlen = sizeof(timer);        if (getsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO,										&timer, &optlen) < 0)            err_sys("SO_SNDTIMEO getsockopt error");		if (verbose)			fprintf(stderr, "SO_SNDTIMEO: %ld.%06ld\n",									timer.tv_sec, timer.tv_usec);#else		fprintf(stderr, "warning: SO_SNDTIMEO not supported by host\n");#endif    }    if (recvdstaddr && udp) {#ifdef	IP_RECVDSTADDR        option = 1;        if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR,										&option, sizeof(option)) < 0)            err_sys("IP_RECVDSTADDR setsockopt error");        option = 0;		optlen = sizeof(option);        if (getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR,										&option, &optlen) < 0)            err_sys("IP_RECVDSTADDR getsockopt error");		if (option == 0)			err_quit("IP_RECVDSTADDR not set (%d)", option);		if (verbose)			fprintf(stderr, "IP_RECVDSTADDR set\n");#else		fprintf(stderr, "warning: IP_RECVDSTADDR not supported by host\n");#endif    }    if (sigio) {#ifdef	FIOASYNC		static void sigio_func(int);		/*		 * Should be able to set this with fcntl(O_ASYNC) or fcntl(FASYNC),		 * but some systems (AIX?) only do it with ioctl().		 *		 * Need to set this for listening socket and for connected socket.		 */		signal(SIGIO, sigio_func);		if (fcntl(sockfd, F_SETOWN, getpid()) < 0)			err_sys("fcntl F_SETOWN error");        option = 1;		if (ioctl(sockfd, FIOASYNC, (char *) &option) < 0)			err_sys("ioctl FIOASYNC error");		if (verbose)			fprintf(stderr, "FIOASYNC set\n");#else		fprintf(stderr, "warning: FIOASYNC not supported by host\n");#endif    }}static voidsigio_func(int signo){	fprintf(stderr, "SIGIO\n");				/* shouldn't printf from a signal handler ... */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -