一、描述符就绪条件

对于引起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. 【锁】MySQL和Oracle行锁比较

    InnoDB INNODB表是索引组织的表,主键是聚集索引,非主键索引都包含主键信息. INNODB默认是行锁. INNODB行锁是通过给索引项加锁来实现的,即只有通过索引条件检索数据,InnoDB才 ...

  2. spring boot jar的支持

  3. hdu 5120 Intersection (圆环面积相交->圆面积相交)

    Problem Description Matt is a big fan of logo design. Recently he falls in love with logo made up by ...

  4. Android中微信抢红包插件原理解析和开发实现

    一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  5. php基于SQLite实现的分页功能示例

    php基于SQLite实现的分页功能. 这里操作数据库文件使用的是前面文章<PHP基于PDO实现的SQLite操作类>中的SQLite数据库操作类. 代码: <?php class ...

  6. vue循环渲染变量类样式

    由于需求的需要,将五种不同的颜色样式通过v-for进行遍历渲染,所以我这里采用绑定类函数进行判断方式.代码: 效果: 灵感来自:https://www.jianshu.com/p/33e181be3d ...

  7. 前端每日实战:103# 视频演示如何用纯 CSS 创作一只监视眼

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/GBzLdy 可交互视频 此视频是可 ...

  8. Toposort(拓扑排序)dfs递归模板

    最近刷了几题拓扑排序的题,记录一下拓扑排序 在有向图中,并且按照一定的规则(题目所给的规则)排序.如果图中出现了有向环的话就无法排序了. int gap[maxn][maxn];//记录下有向边 in ...

  9. 使用Python的PIL模块来进行图片对比

    使用Python的PIL模块来进行图片对比 在使用google或者baidu搜图的时候会发现有一个图片颜色选项,感觉非常有意思,有人可能会想这肯定是人为的去划分的,呵呵,有这种可能,但是估计人会累死, ...

  10. python-django之cookie及session

    Cookie Cookie的由来 Http协议是无状态的 无状态的意思是每次都是独立的请求存在,它的执行情况和结果与前面的请求和后面的请求都无直接关系,它不会受到前面的请求响应情况直接影响,也不会直接 ...