Linux網路程式設計——I/O複用之poll函式
阿新 • • 發佈:2019-02-05
#include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/select.h> #include <sys/time.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <poll.h> int main(int argc,char *argv[]) { int udpfd = 0; int ret = 0; struct pollfd fds[2];//監測檔案描述結構體陣列:2個 struct sockaddr_in saddr; struct sockaddr_in caddr; bzero(&saddr,sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons(8000); saddr.sin_addr.s_addr = htonl(INADDR_ANY); bzero(&caddr,sizeof(caddr)); caddr.sin_family = AF_INET; caddr.sin_port = htons(8000); //建立套接字 if( (udpfd = socket(AF_INET,SOCK_DGRAM, 0)) < 0) { perror("socket error"); exit(-1); } //套接字埠綁字 if(bind(udpfd, (struct sockaddr*)&saddr, sizeof(saddr)) != 0) { perror("bind error"); close(udpfd); exit(-1); } printf("input: \"sayto 192.168.220.X\" to sendmsg to somebody\033[32m\n"); fds[0].fd = 0; //標準輸入描述符 fds[1].fd = udpfd; //udp描述符 fds[0].events = POLLIN; // 普通或優先順序帶資料可讀 fds[1].events = POLLIN; // 普通或優先順序帶資料可讀 while(1) { // 監視並等待多個檔案(標準輸入,udp套接字)描述符的屬性變化(是否可讀) // 沒有屬性變化,這個函式會阻塞,直到有變化才往下執行,這裡沒有設定超時 ret = poll(fds, 2, -1); write(1,"UdpQQ:",6); if(ret == -1){ // 出錯 perror("poll()"); } else if(ret > 0){ // 準備就緒的檔案描述符 char buf[100] = {0}; if( ( fds[0].revents & POLLIN ) == POLLIN ){ // 標準輸入 fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = '\0'; if(strncmp(buf, "sayto", 5) == 0) { char ipbuf[16] = ""; inet_pton(AF_INET, buf+6, &caddr.sin_addr);//給addr套接字地址再賦值. printf("\rsay to %s\n",inet_ntop(AF_INET,&caddr.sin_addr,ipbuf,sizeof(ipbuf))); continue; } else if(strcmp(buf, "exit")==0) { close(udpfd); exit(0); } sendto(udpfd, buf, strlen(buf),0,(struct sockaddr*)&caddr, sizeof(caddr)); } else if( ( fds[1].revents & POLLIN ) == POLLIN ){ //udp套接字 struct sockaddr_in addr; char ipbuf[INET_ADDRSTRLEN] = ""; socklen_t addrlen = sizeof(addr); bzero(&addr,sizeof(addr)); recvfrom(udpfd, buf, 100, 0, (struct sockaddr*)&addr, &addrlen); printf("\r\033[31m[%s]:\033[32m%s\n",inet_ntop(AF_INET,&addr.sin_addr,ipbuf,sizeof(ipbuf)),buf); } } else if(0 == ret){ // 超時 printf("time out\n"); } } return 0; }