一、描述符就绪条件

对于引起select返回套接字“就绪”的条件我们必须讨论得更明确:

(1)满足一下塞个条件中的仍和一个时,一个套接字准备好读。

a)该套接字接收缓冲区中的数据字节数不大于等于套接字接收缓冲区低水位标记的当前大小。相关SO_RCVLOWAT默认值为1

b)该连接的读半部关闭(也就接收了FIN的TCP连接)。对这样的套接字读操作将不阻塞并返回0(返回EOF)

c)该套接字是一个监听套接字且已完成的连接数不为0(accept不阻塞)

d)其上有一个套接字错误待处理。

(2)下列四个条件中任何一个满足时,一个套接字准备好写。

a)该套接字发送发送缓冲区中的可用空间字节数大于等于套接字发送缓冲区低水位标记的当前大小,

并且该套接字已连接,或者该套接字不需要连接。相关SO_SNDLOWAT默认2048

b)该链接写半部关闭。写操作将产生SIGPIPE

c)使用非阻塞式connect套接字已建立连接,或者connect已经以失败告终

d)其上有一个套接字错误待处理。

(3)如果一个套接字存在带外数据或者仍处于带外标记,那么它有异常条件待处理。

二、shutdown函数

#include <sys/socket.h>

int shutdown(int sockfd, int howto);
返回:成功为0,出错-
sockfd:套接字描述符
howto:
SHUT_RD:关闭连接的读这一半,套接字不再有数据可接收
SHUT_WR:关闭连接的写这一半,套接字不再有数据可发送
SHUT_RDWR:连接的读半部和写半部都关闭

str_cli函数(再修订版):

 #include "unp.h"

 void
str_cli(FILE *fp, int sockfd)
{
int maxfdp1, stdineof;
fd_set rset;
char buf[MAXLINE];
int n; stdineof = ;
FD_ZERO(&rset);
for( ; ;) {
if(stdineof == )
FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
maxfdp1 = max(fileno(fp), sockfd) + ;
Select(maxfdp1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd, &rset)) {
if((n = Read(sockfd, buf, MAXLINE)) == ) {
if(stdineof == )
return;
else
err_quit("str_cli: server terminated prematurely");
}
Write(fileno(stdout), buf, n);
}
if(FD_ISSET(fileno(fp), &rset)) {
if((n = Read(fileno(fp), buf, MAXLINE)) == ) {
stdineof = ;
Shutdown(sockfd, SHUT_WR);
FD_CLR(fileno(fp), &rset);
continue;
}
Writen(sockfd, buf, n);
}
}
}

str_cli

三、pselect函数

#include <sys/select.h>
#include <signal.h>
#include <time.h> int pselect(int maxfdp1, fd_set *readset, fd_set *writeset,
fd_set *exceptset, const struct timespec *timeout, const sigset_t *sigmask);
返回:若有就绪描述符则为其数目,若超时则为0,若出错则为-1
maxfdp1:最大描述符集+1
readset:读集
writeset:写集
exceptset:异常集
timeout:延时
sigmask:掩码

pselect()用来等待文件描述词状态的改变,和select()类似,它增加了超时值的精度,并且可以在等待文件描述符“准备好”的同时指定一组信号掩码。

四、poll函数

#include <poll.h>

int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);
返回:若有就绪描述符则为其数目,若超时则为0,若出错则为-1
struct pollfd {
int fd;
short events;
short revents;
}
fdarray:指向结构数组第一个元素的指针
nfds:用于标记数组fds中的结构体元素的总数量
timeout:是poll函数调用阻塞的时间,单位:毫秒

poll的百度示例,和select类似

 #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <poll.h>
#include <fcntl.h>
#include <unistd.h> #define MAX_BUFFER_SIZE 1024
#define IN_FILES 3
#define TIME_DELAY 60*5
#define MAX(a,b) ((a>b)?(a):(b)) int
main(int argc, char **argv)
{
struct pollfd fds[IN_FILES];
char buf[MAX_BUFFER_SIZE];
int i, res, real_read, maxfd;
fds[].fd = ;
if((fds[].fd = open("data1", O_RDONLY|O_NONBLOCK)) < ) {
fprintf(stderr, "open data1 error:%s", strerror(errno));
return ;
}
if((fds[].fd = open("data2", O_RDONLY|O_NONBLOCK)) < ) {
fprintf(stderr, "open data2 error:%s", strerror(errno));
return ;
} for(i=;i<IN_FILES;i++)
fds[i].events = POLLIN; while(fds[].events || fds[].events || fds[].events) {
if(poll(fds, IN_FILES, TIME_DELAY) <= ) {
printf("Poll error\n");
return ;
}
for(i=;i<IN_FILES;i++) {
if(fds[i].revents) {
memset(buf, , MAX_BUFFER_SIZE);
real_read = read(fds[i].fd, buf, MAX_BUFFER_SIZE);
if(real_read < ) {
if(errno != EAGAIN)
return ;
} else if(!real_read) {
close(fds[i].fd);
fds[i].events = ;
} else {
if(i == ) {
if((buf[] == 'q') || (buf[] == 'Q'))
return ;
} else {
buf[real_read] = '\0';
printf("%s", buf);
}
}
} }
}
exit();
}

poll

 #include "unp.h"
#include <limits.h> int
main(int argc, char **argv)
{
int i, maxi, listenfd, connfd, sockfd;
int nready;
ssize_t n;
char buf[MAXLINE];
socklen_t clilen;
struct pollfd client[OPEN_MAX];
struct sockaddr_in cliaddr, servaddr; listenfd = Socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT); Bind(listenfd, (SA *)&servaddr, sizeof(servaddr)); Listen(listenfd, LISTENQ); client[].fd = listenfd;
client[].events = POLLRDNORM;
for(i=;i<OPEN_MAX;i++)
client[i].fd = -;
maxi = ; for( ; ; ) {
nready = Poll(client, maxi+, INFTIM); if(client[].revents & POLLRDNORM) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *)&cliaddr, &clilen); for(i=;i<OPEN_MAX;i++)
if(client[i].fd < ) {
client[i].fd = connfd;
break;
}
if(i == OPEN_MAX)
err_quit("too many clients"); client[i].events = POLLRDNORM;
if(i > maxi)
maxi = i; if(--nready <= )
continue;
}
for(i = ;i<=maxi;i++) {
if((sockfd = client[i].fd) < )
continue;
if(client[i].revents & (POLLRDNORM | POLLERR)) {
if((n = read(sockfd, buf, MAXLINE)) < ) {
if(errno = ECONNRESET) {
Close(sockfd);
client[i].fd = -;
} else
err_sys("read error");
} else if(n == ) {
Close(sockfd);
client[i].fd = -;
} else
Writen(sockfd, buf, n); if(--nready <= )
break;
}
}
}
}

tcp

UNP学习第六章(二)的更多相关文章

  1. UNP学习第六章select

    一.I/O复用典型的网络应用场合 当客户处理多个描述字时,必须使用I/O复用,这在前一段中已做了描述. 一个客户同时处理多个套接口时可能的,但很少出现. 如果一个TCP服务器既要处理监听套接口,又要处 ...

  2. 201671010140. 2016-2017-2 《Java程序设计》java学习第六章

    java学习第六章    本周对与java中的接口,lambda表达式与内部类进行了学习,以下是我在学习中的一些体会:    1.接口: <1>.接口中的所有常量必须是public sta ...

  3. Java基础知识二次学习--第六章 常用类

    第六章 常用类   时间:2017年4月26日16:14:49~2017年4月26日16:56:02 章节:06章_01节~06章_06节 视频长度:20:57+1:15+8:44+1:26+11:2 ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. 【转载】Gradle学习 第六章:构建脚本基础

    转载地址:http://ask.android-studio.org/?/article/11 6.1. Projects and tasks 项目和任务Everything in Gradle si ...

  6. C#高级编程 (第六版) 学习 第六章:运算符和类型强制转换

    第六章 运算符和类型强制转换 1,运算符 类别 运算符 算术运算符 + - * / % 逻辑运算符 & | ^ ~ && || ! 字符串连接运算符 + 增量和减量运算符 ++ ...

  7. UNP学习第五章(二)

    一.POSIX信号处理 信号:告知某进程发生了某个事件的通知(软中断),通常是异步的. 信号可以:由进程发给另一个进程,由内核发给某个进程. 设置信号处理办法,有三个选择: 1.写一个函数,在信号发生 ...

  8. Android的学习第六章(布局二--RelativeLayout)

    今天我们来说一下Android布局中的Relativelayout布局(相对布局) 根据英译过来意思是相对布局,很容易理解,这一样布局使用的是元素与元素之间的微调做到布局的 含义:通过元素与元素之间的 ...

  9. 深度学习框架PyTorch一书的学习-第六章-实战指南

    参考:https://github.com/chenyuntc/pytorch-book/tree/v1.0/chapter6-实战指南 希望大家直接到上面的网址去查看代码,下面是本人的笔记 将上面地 ...

随机推荐

  1. CNN笔记:通俗理解卷积神经网络

    CNN笔记:通俗理解卷积神经网络 2016年07月02日 22:14:50 v_JULY_v 阅读数 250368更多 分类专栏: 30.Machine L & Deep Learning 机 ...

  2. SGU 176 (有源汇最小流)

    转载:http://blog.csdn.net/dan__ge/article/details/51207951 题意:n个节点,m条路径,接下来m行a,b,c,d,如果d等于1,则a到b的流量必须为 ...

  3. 【LeetCode 90】子集 II

    题目链接 [题解] 我们在枚举下一个要取哪个数字的时候. 如 1112233 for (int i = start;i<=n;i++) //其中start-1是上一次取的位置. 如果i>s ...

  4. flutter中的路由跳转

    在前面的基本路由和命名路由中,都演示了如何进行路由跳转,并且在路由跳转以后,可以借用系统自带的按钮就行返回上一级,当然了,也可以自定义按钮返回上一级. 返回上一级 在前面的例子中,当从Home.dar ...

  5. vim中 E212:无法打开并写入文件 的解决办法

    因为centos7刚安装的时候是无法上网的,所以,需要去配置一下ifcfg-ens33文件,但实际上这个文件是只读的文件,root也无法去更改内容,这时候保存的时候需要使用 w ! sudo tee ...

  6. springmvc知识点整理

    1.Springmvc架构 2.Springmvc组件三大组件:处理器映射器,处理器适配器,视图解析器处理器映射器:注解式处理器映射器,对类中标记了@ResquestMapping的方法进行映射,根据 ...

  7. POJ 1860 Currency Exchange (Bellman-Ford)

    题目链接:POJ 1860 Description Several currency exchange points are working in our city. Let us suppose t ...

  8. 10分钟掌握Python-机器学习小项目

    学习机器学习相关技术的最好方式就是先自己设计和完成一些小项目. Python 是一种非常流行和强大的解释性编程语言.不像 R 语言,Python 是个很完整的语言和平台,你既可以用来做研发,也可以用来 ...

  9. mybatis关联查询之一对一查询

    一对一也就是 A 表的一条记录对应 B 表的一条记录,下面的测试数据中,从employee 表来看,一个员工对应一个部门,是一对一关系,如果从部门角度来看,则是一对多的关系,一个部门对应多个员工,本节 ...

  10. ES6几大特性,让你的代码更优美

    1.Default Parameters(默认参数) in ES6 还记得我们以前不得不通过下面方式来定义默认参数:   var link = function (height, color, url ...