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

📄 tcptecho.c

📁 tcp/ip原理的第三卷
💻 C
字号:
/* TCPtecho.c - main, TCPtecho, reader, writer, mstime */

#include <sys/param.h>
#include <sys/filio.h>

#include <poll.h>
#include <stdio.h>
#include <tiuser.h>

extern int	errno, t_errno;
extern char	*sys_errlist[], *t_errlist[];

#define	MIN(x, y)	((x) < (y) ? (x) : (y))

#define	BUFSIZE		4096		/* write buffer size		*/
#define	CCOUNT		64*1024		/* default character count	*/

#define	USAGE	"usage: TCPtecho [ -c count ] host1 host2...\n"

char	*hname[NOFILE];			/* fd to host name mapping	*/
int	rc[NOFILE], wc[NOFILE];		/* read/write character counts	*/
char	buf[BUFSIZE];			/* read/write data buffer	*/
long	mstime();


/*------------------------------------------------------------------------
 * main - concurrent TCP client for ECHO service timing
 *------------------------------------------------------------------------
 */
int
main(argc, argv)
int	argc;
char	*argv[];
{
	int	ccount = CCOUNT;
	int	i, hcount, maxfd, fd;
	struct	pollfd	fds[NOFILE];
	int	one = 1;

	for (fd=0; fd<NOFILE; ++fd)
		fds[fd].fd = -1;

	hcount = 0;
	maxfd = -1;
	for (i=1; i<argc; ++i) {
		if (strcmp(argv[i], "-c") == 0) {
			if (++i < argc && (ccount = atoi(argv[i])))
				continue;
			errexit(USAGE);
		}
		/* else, a host */

		fd = clientTCP(argv[i], "echo");
		if (ioctl(fd, FIONBIO, (char *)&one))
			errexit("can't mark descriptor nonblocking: %s\n",
				sys_errlist[errno]);
		if (fd > maxfd)
			maxfd = fd;
		hname[fd] = argv[i];
		++hcount;
		fds[fd].fd = fd;
		fds[fd].events = POLLIN|POLLOUT;
	}
	TCPtecho(fds, maxfd+1, ccount, hcount);
	exit(0);
}

/*------------------------------------------------------------------------
 * TCPtecho - time TCP ECHO requests to multiple servers
 *------------------------------------------------------------------------
 */
int
TCPtecho(fds, nfds, ccount, hcount)
struct	pollfd	fds[];
int	nfds, ccount, hcount;
{
	int	fd, i;

	for (i=0; i<BUFSIZE; ++i)	/* echo data	*/
		buf[i] = 'D';
	for (fd=0; fd<nfds; ++fd)
		rc[fd] = wc[fd] = ccount;

	(void) mstime((long *)0);	/* set the epoch */

	while (hcount) {
		if (poll(fds, nfds, -1) < 0)
			errexit("poll failed: %s\n",sys_errlist[errno]);
		for (fd=0; fd<nfds; ++fd) {
			if (fds[fd].revents & POLLIN)
				if (reader(fd, fds) == 0)
					hcount--;
			if ((fds[fd].events & POLLOUT) &&
			    (fds[fd].revents & POLLOUT))
				writer(fd, fds);
		}
	}
}

/*------------------------------------------------------------------------
 * reader - handle ECHO reads
 *------------------------------------------------------------------------
 */
int
reader(fd, fds)
int		fd;
struct	pollfd	fds[];
{
	long	now;
	int	cc, flags;

	cc = t_rcv(fd, buf, sizeof(buf), &flags);
	if (cc < 0)
		if (t_errno == TSYSERR)
			errexit("t_rcv: %s\n", sys_errlist[errno]);
		else
			errexit("t_rcv: %s\n", t_errlist[t_errno]);
	if (cc == 0)
		errexit("t_rcv: premature end of file\n");
	rc[fd] -= cc;
	if (rc[fd])
		return 1;
	(void) mstime(&now);
	printf("%s: %d ms\n", hname[fd], now);
	(void) t_close(fd);
	fds[fd].fd = -1;
	return 0;
}

/*------------------------------------------------------------------------
 * writer - handle ECHO writes
 *------------------------------------------------------------------------
 */
int
writer(fd, fds)
int		fd;
struct	pollfd	fds[];
{
	int	cc;

	cc = t_snd(fd, buf, MIN(sizeof(buf), wc[fd]), 0);
	if (cc < 0)
		if (t_errno == TSYSERR)
			errexit("t_snd: %s\n", sys_errlist[errno]);
		else
			errexit("t_snd: %s\n", t_errlist[t_errno]);
	wc[fd] -= cc;
	if (wc[fd] == 0) {
		(void) t_sndrel(fd);
		fds[fd].events &= ~POLLOUT;
	}
}

/*------------------------------------------------------------------------
 * mstime - report the number of milliseconds since Jan 1, 1970
 *------------------------------------------------------------------------
 */
long
mstime(pms)
long	*pms;
{
	static struct timeval	epoch;
	struct timeval		now;

	if (gettimeofday(&now, (struct timezone *)0))
		errexit("gettimeofday: %s\n", sys_errlist[errno]);
	if (!pms) {
		epoch = now;
		return 0;
	}
	*pms = (now.tv_sec - epoch.tv_sec) * 1000;
	*pms += (now.tv_usec - epoch.tv_usec + 500)/ 1000;
	return *pms;
}

⌨️ 快捷键说明

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