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

📄 cliopen.c

📁 TCP/IP详解
💻 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"

int
cliopen(char *host, char *port)
{
	int					fd, i, on;
	char				*protocol;
	unsigned long		inaddr;
	struct sockaddr_in	cli_addr, serv_addr;
	struct servent		*sp;
	struct hostent		*hp;

	protocol = udp ? "udp" : "tcp";

		/* initialize socket address structure */
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;

		/* see if "port" is a service name or number */
	if ( (i = atoi(port)) == 0) {
		if ( (sp = getservbyname(port, protocol)) == NULL)
			err_quit("getservbyname() error for: %s/%s", port, protocol);

		serv_addr.sin_port = sp->s_port;
	} else
		serv_addr.sin_port = htons(i);

	/*
	 * First try to convert the host name as a dotted-decimal number.
	 * Only if that fails do we call gethostbyname().
	 */

	if ( (inaddr = inet_addr(host)) != INADDR_NONE) {
						/* it's dotted-decimal */
		bcopy((char *) &inaddr, (char *) &serv_addr.sin_addr, sizeof(inaddr));

	} else {
		if ( (hp = gethostbyname(host)) == NULL)
			err_quit("gethostbyname() error for: %s", host);

		bcopy(hp->h_addr, (char *) &serv_addr.sin_addr, hp->h_length);
	}

	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,
										(char *) &on, sizeof (on)) < 0)
			err_sys("setsockopt of SO_REUSEADDR error");
	}

	/*
	 * User can specify port number for client to bind.  Only real use
	 * is to see a TCP connection initiated by both ends at the same time.
	 * Also, if UDP is being used, we specifically call bind() to assign
	 * an ephemeral port to the socket.
	 */

	if (bindport != 0 || udp) {
		bzero((char *) &cli_addr, sizeof(cli_addr));
		cli_addr.sin_family      = AF_INET;
		cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);	/* wildcard */
		cli_addr.sin_port        = htons(bindport);

		if (bind(fd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
			err_sys("bind() error");
	}

	/* Need to allocate buffers before connect(), since they can affect
	 * TCP options (window scale, etc.).
	 */

	buffers(fd);
	sockopts(fd, 0);	/* may also want to set SO_DEBUG */

	/*
	 * Connect to the server.  Required for TCP, optional for UDP.
	 */

	if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		err_sys("connect() error");

	if (verbose) {
			/* Call getsockname() to find local address bound to socket:
			   TCP ephemeral port was assigned by connect() or bind();
			   UDP ephemeral port was assigned by bind(). */
		i = sizeof(cli_addr);
		if (getsockname(fd, (struct sockaddr *) &cli_addr, &i) < 0)
			err_sys("getsockname() error");

					/* Can't do one fprintf() since inet_ntoa() stores
					   the result in a static location. */
		fprintf(stderr, "connected on %s.%d ",
					INET_NTOA(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
		fprintf(stderr, "to %s.%d\n",
					INET_NTOA(serv_addr.sin_addr), ntohs(serv_addr.sin_port));
	}

	sockopts(fd, 1);	/* some options get set after connect() */

	return(fd);
}

⌨️ 快捷键说明

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