日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux poll

發(fā)布時間:2023/12/20 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux poll 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Linux poll


poll提供的功能與select類似,不過在處理流設備時,它能夠提供額外的信息。

1、函數(shù)原型
  #include <poll.h>int poll(struct pollfd fd[], nfds_t nfds, int timeout);2、函數(shù)參數(shù):
(1)fd:一個結構數(shù)組,struct pollfd結構如下:
struct pollfd {int fd; //文件描述符short events; //請求的事件short revents; //返回的事件 };  events和revents是通過對代表各種事件的標志進行邏輯或運算構建而成的。events包括要監(jiān)視的事件,poll用已經(jīng)發(fā)生的事件填充revents。poll函數(shù)通過在revents中設置標志肌膚POLLHUP、POLLERR和POLLNVAL來反映相關條件的存在。不需要在events中對于這些標志符相關的比特位進行設置。如果fd小于0, 則events字段被忽略,而revents被置為0.標準中沒有說明如何處理文件結束。文件結束可以通過revents的標識符POLLHUN或返回0字節(jié)的常規(guī)讀操作來傳達。即使POLLIN或POLLRDNORM指出還有數(shù)據(jù)要讀,POLLHUP也可能會被設置。因此,應該在錯誤檢驗之前處理正常的讀操作。
poll函數(shù)的事件標志符值
常量 說明
POLLIN 普通或優(yōu)先級帶數(shù)據(jù)可讀
POLLRDNORM 普通數(shù)據(jù)可讀
POLLRDBAND 優(yōu)先級帶數(shù)據(jù)可讀
POLLPRI 高優(yōu)先級數(shù)據(jù)可讀
POLLOUT 普通數(shù)據(jù)可寫
POLLWRNORM 普通數(shù)據(jù)可寫
POLLWRBAND 優(yōu)先級帶數(shù)據(jù)可寫
POLLERR 發(fā)生錯誤
POLLHUP 發(fā)生掛起
POLLNVAL 描述字不是一個打開的文件
  注意:后三個只能作為描述字的返回結果存儲在revents中,而不能作為測試條件用于events中。
(2)第二個參數(shù)nfds:要監(jiān)視的描述符的數(shù)目。

(3)最后一個參數(shù)timeout:是一個用毫秒表示的時間,是指定poll在返回前沒有接收事件時應該等待的時間。如果 ?它的值為-1,poll就永遠都不會超時。如果整數(shù)值為32個比特,那么最大的超時周期大約是30分鐘。 INFTIM:永遠等待;0:立即返回,不阻塞進程;>0:等待指定毫秒數(shù)。

#ifndef _POLL_H_ #define _POLL_H_#include "wrap.h" #include "client_list.h" #include "server_queue.h"#define SERVER_PORT 6780 #define MAXLINE 100 #define OPEN_MAX 65535 #define TCP_FRAME_SIZE 1200typedef struct {int sockfd; // server socketint port; // server portstruct sockaddr_in addr; // server addrint maxi; // poll maxstruct pollfd event_list[OPEN_MAX]; // poll all event server_queue_t send_queue; // server send data queue to clientserver_queue_t recv_queue; // server recv data queue from clientpthread_t send_thread;pthread_t recv_thread;client_t *client; // client list -- save all client info } server_t;/* recv and send queue frame */ typedef struct {int sockfd; // client socketuint16_t length;char data[TCP_FRAME_SIZE]; } __packed tcp_frame_t;//========================================================== server_t *SocketInit(void);#endif /* _POLL_H_ */ #include "poll.h" #include "debug.h"static server_t *socket_init(void) {int opt = 1, i;server_t *current;current = (server_t *)malloc(sizeof(server_t));current->port = SERVER_PORT;current->sockfd = Socket(AF_INET, SOCK_STREAM, 0);// SOL_SOCKET: port can same, ip notSetsockopt(current->sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));current->addr.sin_family = AF_INET;current->addr.sin_port = htons(current->port);current->addr.sin_addr.s_addr = INADDR_ANY;Bind(current->sockfd, (struct sockaddr *)¤t->addr, sizeof(current->addr));Listen(current->sockfd, MAXLINE);current->event_list[0].fd = current->sockfd;current->event_list[0].events = POLLIN;for(i = 1; i < OPEN_MAX; ++i){current->event_list[i].fd = -1;}current->maxi = current->sockfd;ServerQueueInit(&current->send_queue, TCP_FRAME_SIZE);ServerQueueInit(&current->recv_queue, TCP_FRAME_SIZE);return current; }static void socket_accept(server_t *arg) {server_t *current = arg;struct sockaddr_in addr;int len = sizeof(struct sockaddr_in), i;int new_fd = Accept(current->sockfd, (struct sockaddr *)&addr, &len);debug("new connection client_fd ( %d ) %s: %d\n", new_fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));for(i = 0; i < OPEN_MAX; ++i){if(current->event_list[i].fd < 0){// add new_fd to event_list current->event_list[i].fd = new_fd;current->event_list[i].events = POLLIN;break;}}if(OPEN_MAX == i){printf("too many connects\n");Close(new_fd);return;}if(i > current->maxi){current->maxi = i;}/* add client node */client_t *node = (client_t *)malloc(sizeof(client_t));node->sockfd = new_fd;memcpy(&node->addr, &addr, sizeof(struct sockaddr_in));ClientAdd(node); }static void socket_recv(server_t *arg, int ret) {server_t *current = arg;int i, sockfd, length = 0;tcp_frame_t write;for(i = 1; i <= current->maxi; ++i){if((sockfd = current->event_list[i].fd) < 0){continue;}if(current->event_list[i].revents & (POLLIN | POLLERR)){length = recv(sockfd, write.data, TCP_FRAME_SIZE, 0);if(0 == length){/* delete client node, close connect socket */debug("client[%d] close\n", sockfd);ClientDel(sockfd);Close(sockfd);continue;}else if(length > 0){write.sockfd = sockfd;write.length = length;server_debug(write.data, write.length);// add data to recv_queue, pop in other, if(ServerQueueWrite(&current->recv_queue, (uint8_t *)&write, sizeof(tcp_frame_t)) == 0){debug("push failure...queue full...\n");}}if(--ret <= 0){break;}}} }static void *server_recv_thread(void *arg) {server_t *current = (server_t *)arg;while(1){int timeout = 3000;int ret = Poll(current->event_list, current->maxi, timeout);if(current->event_list[0].revents & POLLIN){socket_accept(current); // a new connect come}if(--ret < 0){continue;}socket_recv(current, ret); // a exsit connect send data to us}Close(current->sockfd);return NULL; }static void *server_send_thread(void *arg) {server_t *current = (server_t *)arg;tcp_frame_t *read = NULL;while(1){//read = (tcp_frame_t*)ServerQueueRead(&current->send_queue, sizeof(tcp_frame_t));if(read != NULL){//server_debug(read->data, read->length);}usleep(100);}return NULL; }server_t * SocketInit(void) {server_t *current = socket_init();debug("create thread...\r\n");pthread_create(&current->send_thread, NULL, server_send_thread, current);pthread_create(&currentt->recv_thread, NULL, server_recv_thread, current);return current; }


總結

以上是生活随笔為你收集整理的Linux poll的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。