其原型为:

#include <poll.h>
int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);

成功时返回 准备好描述字的个数,超时返回0,出错返回 -1

第一个参数是指向一个结构数组第一个元素的指针,每个数组元素都是一个pollfd结构

结构体定义如下:

struct pollfd {int fd;short events;short revents;};

要测试的条件由成员events规定,函数在相应的revents成员中返回描述字的状态。

POLLIN:普通或优先级带数据可读

POLLRDNORM:普通数据可读

POLLRDBAND:优先级带数据可读

POLLPRI: 高优先级数据可读

POLLOUT:普通数据可写

POLLWRNORM:普通数据可写

POLLWRBAND:优先级带数据可写

POLLERR:发生错误

POLLHUP:发生挂起

POLLNVAL:描述字不是一个打开的文件

poll识别三个类别的数据:普通、优先级带和高优先级

参数timeout指定函数返回等待多长时间,它是一个指定等待的毫秒数的正值。

INFTIM:永远等待

0:立即返回,不阻塞

>0:等待指定数目的毫秒数

服务器端:

INFTIM加了头文件#include <poll.h>和#include <sys/stropts.h>还是说无定义,后来自行定义

#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <limits.h>
#include <poll.h>
#include <sys/stropts.h>#define SIN_PORT 9999
#define BUFLEN 128
#define OPEN_MAX 100#ifndef INFTIM
#define INFTIM -1
#endifvoid str_echo(int fd);void sig_child(int signo)
{pid_t pid;int stat;while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {printf("pid %d terminated\n", pid);}}size_t readn(int fd, void *ptr, size_t n)
{char *p = ptr;size_t nleft = n;size_t nread;while (nleft > 0) {if ((nread = read(fd, p, nleft)) < 0) {if (errno == EINTR) nread = 0;else return -1;} else if (nread == 0) break;nleft -= nread;p += nread;}return n - nleft;
}size_t readline(int fd, void *ptr, size_t maxsize)
{char *p = ptr;size_t rc, n;char c;for (n = 1; n < maxsize; n++) {
again:if ((rc = read(fd, &c, 1)) == 1) {*p++ = c;if (c == '\n') break;} else if (rc == 0) {if (n == 1) return 0;else break;} else {if (errno == EINTR) goto again;return -1;}}*p = 0;return n;
}size_t writen(int fd, void *ptr, size_t n)
{char *p = ptr;size_t nleft = n,  nwriten;while (nleft > 0) {if ((nwriten = write(fd, p, nleft)) <= 0) {if (errno == EINTR) nwriten = 0;else return -1;}p += nwriten;nleft -= nwriten;}return n;
}void str_echo(int fd)
{char recvline[BUFLEN];int n;for (;;) {if ((n = readline(fd, recvline, BUFLEN)) == 0) return;printf("received buf=%s", recvline);writen(fd, recvline, n);}
}int main(int argc, char **argv)
{int listenfd, connfd, sockfd;int i, maxi, n;int nready;struct pollfd  client[OPEN_MAX];struct sockaddr_in servaddr, clientaddr;char buf[BUFLEN];socklen_t len;listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd < 0) {printf("socket error :%s\n", strerror(errno));        return -1;}servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SIN_PORT);servaddr.sin_addr.s_addr = htonl(INADDR_ANY);signal(SIGCHLD, sig_child);if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {printf("bind error:%s\n", strerror(errno));close(listenfd);return -1;}if (listen(listenfd, 3) < 0) {printf("listen error:%s\n", strerror(errno));close(listenfd);return -1;}client[0].fd = listenfd;client[0].events = POLLRDNORM;for (i = 1; i < OPEN_MAX; i++) {client[i].fd = -1;}maxi = 0;for (;;) {nready = poll(client, maxi + 1, INFTIM); if (client[0].revents & POLLRDNORM) {len = sizeof(len);connfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);for (i = 1; i < OPEN_MAX; i++) {if (client[i].fd < 0) {client[i].fd = connfd;break;}}if (i == OPEN_MAX) {printf("too many clients\n");return;}client[i].events = POLLRDNORM;if (i > maxi) maxi = i;if (--nready <= 0) continue;}for (i = 1; i <= maxi; i++) {if ((sockfd = client[i].fd) < 0) continue;if (client[i].revents & (POLLRDNORM | POLLERR)) {if ((n = readline(sockfd, buf, BUFLEN)) < 0) {if (errno == ECONNRESET) {close(sockfd);client[i].fd = -1;}} else if (n == 0) {close(sockfd);client[i].fd = -1;} else {writen(sockfd, buf, n);}}if (--nready <= 0) break;}}return 0;
}

客户端:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>#define SIN_PORT 9999
#define BUF_LEN 256
#define max(a, b) ((a) > (b) ? (a) : (b))size_t readline(int fd, void *ptr, int maxsize)
{char *p = ptr;char c;int rc;int n;for (n = 1; n < maxsize; n++) {again:if ((rc = read(fd, &c, 1)) == 1) {*p++ = c;if (c == '\n') break; } else if (rc == 0) {if (n == 1) return 0;else break;}else {if (errno == EINTR) goto again;else return -1;}}*p = 0;return n;
}size_t readn(int fd, void *ptr, size_t n)
{char *p = ptr;int nleft = n;int nread;while (nleft > 0) {if ((nread = read(fd, p, nleft)) < 0) {if (errno == EINTR) nread = 0;else return -1;} else if (nread == 0) break;nleft -= nread;p += nread;}return n - nleft;
}size_t writen(int fd, void *ptr, size_t n)
{size_t nwriten;size_t nleft = n;char *p = ptr;while (nleft > 0) {if ((nwriten = write(fd, p, nleft)) <= 0) {if (errno == EINTR) nwriten = 0;else return -1;}nleft -= nwriten;p += nwriten;}return n;
}void str_cli(FILE *file, int fd)
{char recvline[BUF_LEN], sendline[BUF_LEN];int maxfdp1;fd_set fdset;int ret;int stdineof = 0;FD_ZERO(&fdset);for(;;) {if (stdineof == 0)FD_SET(fileno(file), &fdset);FD_SET(fd, &fdset);maxfdp1 = max(fileno(file), fd) + 1;ret = select(maxfdp1, &fdset, NULL, NULL, NULL);   if (ret <= 0) {continue;}//printf("ret=%d\n", ret);if (FD_ISSET(fd, &fdset)) {if (readline(fd, recvline, BUF_LEN) == 0) {if (stdineof == 1)return;else {printf("readline error:%s\n", strerror(errno));return;}}fputs(recvline, stdout);} if (FD_ISSET(fileno(file), &fdset)) {memset(sendline, 0x00, sizeof(sendline));if (fgets(sendline, BUF_LEN, file) == NULL) {//printf("fgets error:%s\n", strerror(errno));stdineof = 1;shutdown(fd, SHUT_WR);FD_CLR(fileno(file), &fdset);continue;}//printf("len=%d\n", strlen(sendline));writen(fd, sendline, strlen(sendline));}   }
}int main(int argc, char** argv)
{struct sockaddr_in serveraddr;int sockfd;#ifndef ONLINE_JUDGE//freopen("6.4Client.c", "r", stdin);
#endifsockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {printf("socket error:%s\n", strerror(errno));return -1;}   serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(SIN_PORT);if (inet_pton(AF_INET, argv[1], &serveraddr.sin_addr) != 1) {printf("inet_pton error:%s\n", strerror(errno));close(sockfd);return -1;}if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) {printf("connect error:%s\n", strerror(errno));close(sockfd);return -1;}str_cli(stdin, sockfd);exit(0);}

网络编程学习笔记(poll函数)相关推荐

  1. 网络编程学习笔记(shutdown函数)

    终止网络连接的正常方法是close,但close有两个限制,可由shutdown来避免 1.close将描述字的访问计数减1,仅在此计数为0时才关闭套接口.用shutdown可以激发TCP的正常连接终 ...

  2. 网络编程学习笔记(socketpair函数)

    socketpair函数建立一对相互连接的套接口,这个函数只对Unix域套接口适用,其定义如下: #include <sys/socket.h> int socketpair(int fa ...

  3. 网络编程学习笔记(getnameinfo函数)

    这个函数与getaddrinfo互补,它以一个套接口地址为参数,返回一个描述主机的字符串和一个描述服务的字符串.其函数原型如下: #include <netdb.h> int getnam ...

  4. 网络编程学习笔记(udp_client函数)

    创建一个未连接的UDP套接口的客户函数,其代码如下: #include <netdb.h> #include <sys/socket.h> #include <netin ...

  5. 网络编程学习笔记(getaddrinfo函数)

    函数getaddrinfo在库函数中隐藏了所有协议依赖性.应用 程序只需要处理由getaddrinfo填写的套接口地址结构.其函数原型为: #include <netdb.h> int g ...

  6. 网络编程学习笔记(uname函数)

    函数uname返回当前主机的名字.经常与gethostbyname一起用来确定本地主机的IP地址.其原型为: #include <sys/utsname.h> int uname(stru ...

  7. 网络编程学习笔记(gethostbyaddr函数)

    函数gethostbyaddr取一个二进制的IP地址并试图找到相应于此地址的主机名,与gethostbyname的行为恰好相反.gethostbyname感兴趣的是h_name 其原型为: #incl ...

  8. 网络编程学习笔记(gethostbyname2函数与IPv6支持)

    其原型为: #include <netdb.h> struct hostent * gethostbyname2(const char *hostname, int family); 成功 ...

  9. 网络编程学习笔记(gethostbyname函数)

    #include <netdb.h> struct hostent* gethostbyname(const char* hostname); 成功,返回非空指针,出错返回空指针,同时设置 ...

最新文章

  1. 个人知识管理的29个原则--摘录
  2. spring boot 的常用注解使用 总结
  3. android查询竞价处理,公平可靠的竞价方式,应对越来越高的流量获取成本,如何解决推广费用过高的问题可能是...
  4. CentOS Linux下VNC Server远程桌面配置详解
  5. 成熟期滞后状态的云计算:应重视云存储及安全策略
  6. 无工具arp病毒检测
  7. 如何实现两个数据库之间的同步
  8. hive2 java连接_用Java代码通过JDBC连接Hiveserver2
  9. Android 学习资源收集
  10. 为何MAC的JDK/JRE大小这么小?
  11. Matlab猜数字游戏GUI界面设计
  12. 360免费wifi设置位置服务器,win10系统使用360免费wifi的操作方法
  13. unable to find valid certification path to requested target的异常解决办法
  14. Android Room,编译成功,倒是 build APK 失败提示: 无法访问:ActivityCompatApi23
  15. acer加固态硬盘,hdd放到光驱位,BIOS没有设置固态硬盘启动选项
  16. 【C#】工具篇 vspd虚拟串口的安装
  17. 思岚科技陈士凯:场景化应用或成服务机器人行业突破口
  18. 一剂拯救“国足”的终极药方:全面 AI 化
  19. 重磅!华为搜索引擎面世
  20. Asp.net core MVC paypal支付、回调——app支付

热门文章

  1. asp.net select Case条件语句的使用方法
  2. Linux oracle数据库自动备份自动压缩脚本代码
  3. Linux学习之线程封装四:基于接口的封装
  4. python爬虫教程视频下载-利用Python网络爬虫获取电影天堂视频下载链接【详细教程】...
  5. python open 打开是什么类型的文件-详解Python中open()函数指定文件打开方式的用法...
  6. python学到什么程度可以写爬虫-月薪2万的爬虫工程师,Python需要学到什么程度?...
  7. python语言命令大全-python常用命令
  8. python序列类型-python学习—序列类型、列表、元组
  9. python项目-你肯定想学习的顶级Python项目(附代码)
  10. python生成折线图-python 生成图表