UNIX网络编程——shutdown函数(I/O复用并发服务器)

        上述这篇文章http://blog.csdn.net/songshimvp1/article/details/51838990中,第4点,以批量处理方式运行客户,仅仅使用select无法实现TCP的半关闭——给服务器发送一个FIN,告诉它我们完成了数据的发送,但是仍然保持套接字描述符打开以便读取


1、shutdown函数的作用

(1)close把描述符的引用计数减1,仅在该计数变为0时才关闭套接字。使用shutdown可以不管引用计数就激发TCP正常的连接终止序列;

(2)close终止读和写两个方向的数据传送。既然TCP连接是全双工的,有些时候我们需要告知对端我们已完成数据的发送,即使对端还仍有数据要发给我们。在上篇文章中批量输入时调用shutdown将如图:


2、shutdown函数原型定义

#include <sys/socket.h>

int shutdown(int sockfd,  int howto);

//shutdown函数的行为依赖于参数howto
/*
howto:
(1)SHUT_RD:关闭连接读这一半;
(2)SHUT_WR:关闭连接写这一半;
(3)SHUT_RDWR:连接的读半部和写半部都关闭(相当于先调用SHUT_RD,再调用SHUT_WR);
*/

3、shutdown函数的使用

(1)使用select目的:只要服务器关闭它那一端的连接就通知我们(我们可以立即获取到服务器关闭的通知);

(2)使用shutdown目的:正确地处理批量输入;

(3)废弃以文本行,改而针对缓冲区操作;

#include	"unp.h"

void
str_cli(FILE *fp, int sockfd)
{
	int			maxfdp1, stdineof;
	fd_set		rset;
	char		buf[MAXLINE];
	int		n;

	stdineof = 0;
	FD_ZERO(&rset);
	for ( ; ; ) {
		if (stdineof == 0)
			FD_SET(fileno(fp), &rset);    // 对应于标准I/O的fp指针
		FD_SET(sockfd, &rset);                // 对应于套接字scokfd 
		maxfdp1 = max(fileno(fp), sockfd) + 1;//计算上面两个描述符的最大值 
		Select(maxfdp1, &rset, NULL, NULL, NULL);   //阻塞于select,timeout为NULL,阻塞到某个描述符就绪为止  

		//可以随时获知服务器是否关闭

		if (FD_ISSET(sockfd, &rset)) {	/* socket is readable */   //如果套接字可读
			if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {           //读回回射文本
				if (stdineof == 1)
					return;		/* normal termination */
				else
					err_quit("str_cli: server terminated prematurely");
			}

			Write(fileno(stdout), buf, n);
		}

		if (FD_ISSET(fileno(fp), &rset)) {  /* input is readable */    //如果标准输入可读
			if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) {          //读入  
				stdineof = 1;
				Shutdown(sockfd, SHUT_WR);	/* send FIN */ //调用shutdown,关闭写,发送FIN
				FD_CLR(fileno(fp), &rset);
				continue;
			}

			Writen(sockfd, buf, n);
		}
	}
}

(把这段代码和上一篇文章第四点中的代码对比,你会发现很多东西)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值