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

📄 servopen.c

📁 unix网络编程卷1:套接口API的全书源码
💻 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"intservopen(char *host, char *port){	int					fd, newfd, i, on, pid;	const char			*protocol;	struct in_addr		inaddr;	struct servent		*sp;	protocol = udp ? "udp" : "tcp";		/* Initialize the socket address structure */	bzero(&servaddr, sizeof(servaddr));	servaddr.sin_family      = AF_INET;		/* Caller normally wildcards the local Internet address, meaning		   a connection will be accepted on any connected interface.		   We only allow an IP address for the "host", not a name. */	if (host == NULL)		servaddr.sin_addr.s_addr = htonl(INADDR_ANY);		/* wildcard */	else {		if (inet_aton(host, &inaddr) == 0)			err_quit("invalid host name for server: %s", host);		servaddr.sin_addr = inaddr;	}		/* See if "port" is a service name or number */	if ( (i = atoi(port)) == 0) {		if ( (sp = getservbyname(port, protocol)) == NULL)			err_ret("getservbyname() error for: %s/%s", port, protocol);		servaddr.sin_port = sp->s_port;	} else		servaddr.sin_port = htons(i);	if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)		err_sys("socket() error");	if (reuseaddr) {		on = 1;		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)			err_sys("setsockopt of SO_REUSEADDR error");	}#ifdef	SO_REUSEPORT	if (reuseport) {		on = 1;		if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)			err_sys("setsockopt of SO_REUSEPORT error");	}#endif		/* Bind our well-known port so the client can connect to us. */	if (bind(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)		err_sys("can't bind local address");	join_mcast(fd, &servaddr);	if (udp) {		buffers(fd);		if (foreignip[0] != 0) {	/* connect to foreignip/port# */			bzero(&cliaddr, sizeof(cliaddr));			if (inet_aton(foreignip, &cliaddr.sin_addr) == 0)				err_quit("invalid IP address: %s", foreignip);			cliaddr.sin_family = AF_INET;			cliaddr.sin_port   = htons(foreignport);				/* connect() for datagram socket doesn't appear to allow				   wildcarding of either IP address or port number */			if (connect(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr))																		  < 0)				err_sys("connect() error");					}		sockopts(fd, 1);		return(fd);		/* nothing else to do */	}	buffers(fd);		/* may set receive buffer size; must do here to get						   correct window advertised on SYN */	sockopts(fd, 0);	/* only set some socket options for fd */	listen(fd, listenq);	if (pauselisten)		sleep_us(pauselisten*1000);		/* lets connection queue build up */	if (dofork)		TELL_WAIT();			/* initialize synchronization primitives */	for ( ; ; ) {		i = sizeof(cliaddr);		if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr, &i)) < 0)			err_sys("accept() error");		if (dofork) {			if ( (pid = fork()) < 0)				err_sys("fork error");			if (pid > 0) {				close(newfd);	/* parent closes connected socket */				WAIT_CHILD();	/* wait for child to output to terminal */				continue;		/* and back to for(;;) for another accept() */			} else {				close(fd);		/* child closes listening socket */			}		}			/* child (or iterative server) continues here */		if (verbose) {				/* Call getsockname() to find local address bound to socket:				   local internet address is now determined (if multihomed). */			i = sizeof(servaddr);			if (getsockname(newfd, (struct sockaddr *) &servaddr, &i) < 0)				err_sys("getsockname() error");						/* Can't do one fprintf() since inet_ntoa() stores						   the result in a static location. */			fprintf(stderr, "connection on %s.%d ",					INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));			fprintf(stderr, "from %s.%d\n",					INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port));		}		buffers(newfd);		/* setsockopt() again, in case it didn't propagate							   from listening socket to connected socket */		sockopts(newfd, 1);	/* can set all socket options for this socket */		if (dofork)			TELL_PARENT(getppid());	/* tell parent we're done with terminal */		return(newfd);	}}

⌨️ 快捷键说明

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