• epoll代码示例


      1 #include <errno.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <sys/types.h>
      5 #include <sys/socket.h>
      6 #include <netinet/in.h>
      7 #include <arpa/inet.h>
      8 #include <iostream>
      9 #include <sys/epoll.h>
     10 
     11 using namespace std;
     12 
     13 int main(int argc, char *argv[])
     14 {
     15     if (argc != 3)
     16     {
     17         cout << "usage: " << argv[0] << " ip port" << endl;
     18         return -1;
     19     }
     20 
     21     char *szIp = argv[1];
     22     in_addr_t iIp = inet_addr(szIp);
     23     if (iIp == INADDR_NONE)
     24     {
     25         cerr << "fail to parse ip: " << szIp << endl;
     26         return -1;
     27     }
     28     char *pEnd = NULL;
     29     uint16_t usPort = strtoul(argv[2], &pEnd, 10);
     30     if (*pEnd != '')
     31     {
     32         cerr << "fail to parse port: " << argv[2] << endl;
     33         return -1;
     34     }
     35 
     36     int iSockFd = socket(AF_INET, SOCK_STREAM, 0);
     37     if (iSockFd < 0)
     38     {
     39         cerr << "fail to create socket, err: " << strerror(errno) << endl;
     40         return -1;
     41     }
     42     cout << "create socket fd " << iSockFd << endl;
     43 
     44     sockaddr_in oAddr;
     45     memset(&oAddr, 0, sizeof(oAddr));
     46     oAddr.sin_family = AF_INET;
     47     oAddr.sin_addr.s_addr = iIp;
     48     oAddr.sin_port = htons(usPort);
     49     if (bind(iSockFd, (sockaddr *)&oAddr, sizeof(oAddr)) < 0)
     50     {
     51         cerr << "fail to bind addr " << szIp << ":" << usPort << ", err: " << strerror(errno) << endl;
     52         return -1;
     53     }
     54     cout << "bind addr " << szIp << ":" << usPort << endl;
     55 
     56     if (listen(iSockFd, 100) < 0)
     57     {
     58         cerr << "fail to listen on " << szIp << ":" << usPort << ", err: " << strerror(errno) << endl;
     59     }
     60     cout << "listen on socket fd " << iSockFd << endl;
     61     
     62     int iEpollFd = epoll_create(1024);
     63     if (iEpollFd < 0)
     64     {
     65         cerr << "fail to create epoll, err: " << strerror(errno) << endl;
     66         return -1;
     67     }
     68 
     69     epoll_event oEvent;
     70     oEvent.events = EPOLLIN;
     71     oEvent.data.fd = iSockFd;
     72     if (epoll_ctl(iEpollFd, EPOLL_CTL_ADD, iSockFd, &oEvent) < 0)
     73     {
     74         cerr << "fail to add listen fd to epoll, err: " << strerror(errno) << endl;
     75         return -1;
     76     }
     77 
     78     epoll_event aoEvents[1024];
     79     uint8_t acRecvBuf[1024 * 1024];
     80     while (true)
     81     {
     82         int iFdCnt = epoll_wait(iEpollFd, aoEvents, 1024, -1);
     83         if (iFdCnt < 0)
     84         {
     85             cerr << "epoll wait error, err: " << strerror(errno) << endl;
     86             return -1;
     87         }
     88 
     89         for (int i = 0; i < iFdCnt; i++)
     90         {
     91             if (aoEvents[i].data.fd == iSockFd)
     92             {
     93                 sockaddr_in oClientAddr;
     94                 socklen_t iAddrLen = sizeof(oClientAddr);
     95                 int iAcceptFd = accept(iSockFd, (sockaddr *)&oClientAddr, &iAddrLen);
     96                 if (iAcceptFd < 0)
     97                 {
     98                     cerr << "fail to accpet, err: " << strerror(errno) << endl;
     99                     continue;
    100                 }
    101                 cout << "recv connection from " << inet_ntoa(oClientAddr.sin_addr) << ":" << ntohs(oClientAddr.sin_port) << endl;
    102 
    103                 oEvent.events = EPOLLIN;
    104                 oEvent.data.fd = iAcceptFd;
    105                 if (epoll_ctl(iEpollFd, EPOLL_CTL_ADD, iAcceptFd, &oEvent) < 0)
    106                 {
    107                     close(iAcceptFd);
    108                     cerr << "fail to add fd to epoll, err: " << strerror(errno) << endl;
    109                     continue;
    110                 }
    111             }
    112             else
    113             {
    114                 int iCurFd = aoEvents[i].data.fd;
    115                 ssize_t iRecvLen = recv(iCurFd, acRecvBuf, sizeof(acRecvBuf), 0);
    116                 if (iRecvLen < 0)
    117                 {
    118                     cerr << "fail to recv, close connection, err: " << strerror(errno) << endl;
    119                     if (epoll_ctl(iEpollFd, EPOLL_CTL_DEL, iCurFd, NULL) < 0)
    120                     {
    121                         cerr << "fail to del fd from epoll, err: " << strerror(errno) << endl;
    122                     }
    123                     close(iCurFd);
    124                     continue;
    125                 }
    126                 if (iRecvLen == 0)
    127                 {
    128                     cout << "connection closed by client" << endl;
    129                     if (epoll_ctl(iEpollFd, EPOLL_CTL_DEL, iCurFd, NULL) < 0)
    130                     {
    131                         cerr << "fail to del fd from epoll, err: " << strerror(errno) << endl;
    132                     }
    133                     close(iCurFd);
    134                     continue;
    135                 }
    136                 cout << "recv data len: " << iRecvLen << endl;
    137 
    138                 ssize_t iSendLen = send(iCurFd, acRecvBuf, iRecvLen, 0);
    139                 if (iSendLen < 0)
    140                 {
    141                     cerr << "fail to send, err: " << strerror(errno) << endl;
    142                     if (epoll_ctl(iEpollFd, EPOLL_CTL_DEL, iCurFd, NULL) < 0)
    143                     {
    144                         cerr << "fail to del fd from epoll, err: " << strerror(errno) << endl;
    145                     }
    146                     close(iCurFd);
    147                     break;
    148                 }
    149                 cout << "echo to client, len: " << iSendLen << endl;
    150             }
    151         }
    152     }
    153 }
  • 相关阅读:
    QA的几个经典问题(1)
    QA的几个经典问题(2)
    通过Android录音进行简单音频分析
    Android在TextView中实现RichText风格
    Handler Should be static or leaks Occur?
    如何查看华为EMUI系统APK源码?
    ServiceManager: Permmission failure: android.permission.RECORD_AUDIO
    Android 4.4以上的存储读写权限
    如何使用Android中hide的类和方法进行开发?
    在Mac mini上编译Android源码
  • 原文地址:https://www.cnblogs.com/glacierh/p/4928279.html
Copyright © 2020-2023  润新知