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

📄 send.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			_res_perror("send");		(void) close(sock);		return(-1);	}/* * Wait for the arrival of a reply, timeout, or error message. */wait:	n = recvsock(sock, answer, anslen);	if (n <= 0)	{		if (bitset(RES_DEBUG, _res.options))			_res_perror("recvfrom");		(void) close(sock);		return(-1);	}/* * Make sure it is the proper response by checking the packet id. */	if (qp->id != bp->id)	{		if (bitset(RES_DEBUG, _res.options))		{			printf("old answer:\n");			fp_query(answer, stdout);		}		goto wait;	}/* * Never leave the socket open. */	(void) close(sock);	return(n);}#endif /*HOST_RES_SEND*//*** _RES_CONNECT -- Connect to a stream (virtual circuit) socket** ------------------------------------------------------------****	Returns:**		0 if successfully connected.**		-1 in case of failure or timeout.****	Note that we use _res.retrans to override the default**	connect timeout value.*/static jmp_buf timer_buf;static sigtype_t/*ARGSUSED*/timer(sig)int sig;{	longjmp(timer_buf, 1);}int_res_connect(sock, addr, addrlen)input int sock;input struct sockaddr_in *addr;		/* the server address to connect to */input int addrlen;{	if (setjmp(timer_buf) != 0)	{		errno = ETIMEDOUT;		setalarm(0);		return(-1);	}	(void) signal(SIGALRM, timer);	setalarm(_res.retrans);	if (connect(sock, (struct sockaddr *)addr, addrlen) < 0)	{		if (errno == EINTR)			errno = ETIMEDOUT;		setalarm(0);		return(-1);	}	setalarm(0);	return(0);}/*** _RES_WRITE -- Write the query buffer via a stream socket** --------------------------------------------------------****	Returns:**		Length of buffer if successfully transmitted.**		-1 in case of failure (error message is issued).****	The query is sent in two steps: first a single word with**	the length of the buffer, followed by the buffer itself.*/int_res_write(sock, buf, bufsize)input int sock;input char *buf;			/* address of formatted query buffer */input int bufsize;			/* length of query buffer */{	u_short len;/* * Write the length of the query buffer. */	len = htons(bufsize);	if (write(sock, (char *)&len, sizeof(len)) != sizeof(len))	{		_res_perror("write query length");		return(-1);	}/* * Write the query buffer itself. */	if (write(sock, buf, bufsize) != bufsize)	{		_res_perror("write query");		return(-1);	}	return(bufsize);}/*** _RES_READ -- Read the answer buffer via a stream socket** -------------------------------------------------------****	Returns:**		Length of buffer if successfully received.**		-1 in case of failure (error message is issued).****	The answer is read in two steps: first a single word which**	gives the length of the buffer, followed by the buffer itself.**	If the answer is too long to fit into the supplied buffer,**	only the portion that fits will be stored, the residu will be**	flushed, and the truncation flag will be set.*/int_res_read(sock, buf, bufsize)input int sock;output char *buf;			/* address of buffer to store answer */input int bufsize;			/* maximum size of answer buffer */{	u_short len;	char *buffer;	int buflen;	int reslen;	register int n;	/* set stream timeout for recvsock */	timeout = 60;/* * Read the length of answer buffer. */	buffer = (char *)&len;	buflen = sizeof(len);	while (buflen > 0 && (n = recvsock(sock, buffer, buflen)) > 0)	{		buffer += n;		buflen -= n;	}	if (buflen != 0)	{		_res_perror("read answer length");		return(-1);	}/* * Terminate if length is zero. */	len = ntohs(len);	if (len == 0)		return(0);/* * Check for truncation. */	reslen = 0;	if ((int)len > bufsize)	{		reslen = len - bufsize;		len = bufsize;	}/* * Read the answer buffer itself. */	buffer = buf;	buflen = len;	while (buflen > 0 && (n = recvsock(sock, buffer, buflen)) > 0)	{		buffer += n;		buflen -= n;	}	if (buflen != 0)	{		_res_perror("read answer");		return(-1);	}/* * Discard the residu to keep connection in sync. */	if (reslen > 0)	{		HEADER *bp = (HEADER *)buf;		char resbuf[PACKETSZ];		buffer = resbuf;		buflen = reslen < sizeof(resbuf) ? reslen : sizeof(resbuf);		while (reslen > 0 && (n = recvsock(sock, buffer, buflen)) > 0)		{			reslen -= n;			buflen = reslen < sizeof(resbuf) ? reslen : sizeof(resbuf);		}		if (reslen != 0)		{			_res_perror("read residu");			return(-1);		}		if (bitset(RES_DEBUG, _res.options))			(void) fprintf(stderr, "response truncated\n");		/* set truncation flag */		bp->tc = 1;	}	return(len);}/*** RECVSOCK -- Read from stream or datagram socket with timeout** ------------------------------------------------------------****	Returns:**		Length of buffer if successfully received.**		-1 in case of failure or timeout.****	Inputs:**		The global variable timeout should have been**		set with the desired timeout value in seconds.*/static intrecvsock(sock, buffer, buflen)input int sock;output char *buffer;			/* current buffer address */input int buflen;			/* remaining buffer size */{	fd_set fds;	struct timeval wait;	register int n;	wait.tv_sec = timeout;	wait.tv_usec = 0;	/* FD_ZERO(&fds); */	bzero((char *)&fds, sizeof(fds));	FD_SET(sock, &fds);/* * Wait for the arrival of data, or timeout. */	n = select(FD_SETSIZE, &fds, (fd_set *)NULL, (fd_set *)NULL, &wait);	if (n <= 0)	{		if (n == 0)			errno = ETIMEDOUT;		return(-1);	}/* * Fake an error if nothing was actually read. */	n = recv(sock, buffer, buflen, 0);	if (n == 0)		errno = ECONNRESET;	return(n);}/*** _RES_PERROR -- Issue perror message including host info** -------------------------------------------------------****	Returns:**		None.****	The address and name of the server host must be set**	in advance via _res_setaddr().*/static struct in_addr curaddr;	/* current address of server host */static char *curhost = NULL;	/* current name of server host */void_res_setaddr(sin, host)input struct sockaddr_in *sin;		/* address of host to connect to */input char *host;			/* name of host to connect to */{	curaddr = sin->sin_addr;	curhost = host;}void_res_perror(message)input char *message;			/* perror message string */{	int save_errno;	save_errno = errno;	if (curaddr.s_addr)		(void) fprintf(stderr, "%s ", inet_ntoa(curaddr));	if (curhost)		(void) fprintf(stderr, "(%s) ", curhost);	errno = save_errno;	perror(message);}

⌨️ 快捷键说明

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