#include "local.h" #include "utils.h" using namespace std; // 存放客戶端socket描述符的list list<int> clients_list; int main(int argc, char *argv[]) { int listener; //監聽socket struct sockaddr_in addr, their_addr; addr.sin_family = PF_INET; addr.sin_port = htons(SERVER_PORT); addr.sin_addr.s_addr = inet_addr(SERVER_HOST); socklen_t socklen; socklen = sizeof(struct sockaddr_in); static struct epoll_event ev, events[EPOLL_SIZE]; ev.events = EPOLLIN | EPOLLET; //對讀感興趣,邊沿觸發 char message[BUF_SIZE]; int epfd; //epoll描述符 clock_t tStart; //計算程序運行時間 int client, res, epoll_events_count; CHK2(listener, socket(PF_INET, SOCK_STREAM, 0)); //初始化監聽socket setnonblocking(listener); //設置監聽socket為不阻塞 CHK(bind(listener, (struct sockaddr *)&addr, sizeof(addr))); //綁定監聽socket CHK(listen(listener, 1)); //設置監聽 CHK2(epfd,epoll_create(EPOLL_SIZE)); //創建一個epoll描述符,并將監聽socket加入epoll ev.data.fd = listener; CHK(epoll_ctl(epfd, EPOLL_CTL_ADD, listener, &ev)); //把被監聽的fd和監聽的事件放入epoll的文件描述符中 // while(1) { CHK2(epoll_events_count,epoll_wait(epfd, events, EPOLL_SIZE, EPOLL_RUN_TIMEOUT)); tStart = clock(); for(int i = 0; i < epoll_events_count ; i++) { if(events[i].data.fd == listener) //新的連接到來,將連接添加到epoll中,并發送歡迎消息 { CHK2(client,accept(listener, (struct sockaddr *) &their_addr, &socklen)); setnonblocking(client); ev.data.fd = client; CHK(epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ev)); clients_list.push_back(client); // 添加新的客戶端到list bzero(message, BUF_SIZE); res = sprintf(message, STR_WELCOME, client); CHK2(res, send(client, message, BUF_SIZE, 0)); }else { CHK2(res,handle_message(events[i].data.fd)); //注意:這里并沒有調用epoll_ctl重新設置socket的事件類型,但還是可以繼續收到客戶端發送過來的信息 } } printf("Statistics: %d events handled at: %.2f second(s)\n", epoll_events_count, (double)(clock() - tStart)/CLOCKS_PER_SEC); } close(listener); close(epfd); return 0; } int handle_message(int client) { char buf[BUF_SIZE], message[BUF_SIZE]; bzero(buf, BUF_SIZE); bzero(message, BUF_SIZE); int len; CHK2(len,recv(client, buf, BUF_SIZE, 0)); //接受客戶端信息 if(len == 0) //客戶端關閉或出錯,關閉socket,并從list移除socket { CHK(close(client)); clients_list.remove(client); } else //向客戶端發送信息 { if(clients_list.size() == 1) { CHK(send(client, STR_NOONE_CONNECTED, strlen(STR_NOONE_CONNECTED), 0)); return len; } sprintf(message, STR_MESSAGE, client, buf); list<int>::iterator it; for(it = clients_list.begin(); it != clients_list.end(); it++) { if(*it != client) { CHK(send(*it, message, BUF_SIZE, 0)); } } } return len; }
另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
網頁標題:epoll-創新互聯
網站網址:http://vcdvsql.cn/article0/cscpoo.html
成都網站建設公司_創新互聯,為您提供網站設計、動態網站、品牌網站設計、品牌網站制作、云服務器、自適應網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯