简单通讯聊天 群聊功能 Windows下的客户端 Linux下的epoll服务器

发布于 2019-09-26 作者 风铃 51次 浏览 版块 前端

1 服务器代码 Linux eclipse C++

  1 //============================================================================
      2 // Name        : epollServer.cpp
      3 // Author      : fangjunmin
      4 // Version     :
      5 // Copyright   : Your copyright notice
      6 // Description : Hello World in C++, Ansi-style
      7 //============================================================================
      8 
      9 #include <sys/socket.h>
     10 #include <netinet/in.h>
     11 #include <iostream>
     12 #include <stdio.h>
     13 #include <arpa/inet.h>
     14 #include <errno.h>
     15 #include <sys/epoll.h>
     16 #include <map>
     17 #include <vector>
     18 #include <memory.h>
     19 #include "encode.h"
     20 #include <stddef.h>
     21 
     22 using namespace std;
     23 
     24 int g_epfd = -1;
     25 int g_listen_fd = -1;
     26 u_short g_listen_port = 8000;
     27 
     28 
     29 typedef map<int, int> mapClient ;
     30 typedef map<int, int>::iterator itmapClient ;
     31 typedef map<int, int>::const_iterator citmapClient ;
     32 
     33 typedef vector<int> vecClient ;
     34 typedef vecClient::iterator itvecClient ;
     35 typedef vecClient::const_iterator citvecClient ;
     36 
     37 mapClient g_mapClient;
     38 vecClient g_vecCLient;
     39 
     40 void InitListen();
     41 void StartEpoll();
     42 void BoardCast(const char* msg, long int nLen);
     43 void removeFd(int fd);
     44 
     45 int main()
     46 {
     47     cout << "!!!Hello epoll!!!" << endl; // prints !!!Hello epoll!!!
     48 
     49     InitListen();
     50     StartEpoll();
     51     return 0;
     52 }
     53 
     54 void InitListen()
     55 {
     56     g_listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
     57     if (g_listen_fd == -1)
     58     {
     59         return ;
     60     }
     61 
     62     struct sockaddr_in sin;
     63     //bzero(&sin, sizeof(struct sockaddr_in));
     64     sin.sin_family = AF_INET;
     65     sin.sin_addr.s_addr = INADDR_ANY;
     66     sin.sin_port = htons(g_listen_port);
     67 
     68     if (bind(g_listen_fd, (struct sockaddr *) &sin, sizeof(struct sockaddr)) != 0)
     69     {
     70         printf("bind error: %d\\n", errno);
     71         return ;
     72     }
     73 
     74     if (listen(g_listen_fd, 5) != 0)
     75     {
     76         printf("listen error!\\n");
     77         return ;
     78     }
     79 }
     80 
     81 void StartEpoll()
     82 {
     83     int nSize = 5;
     84     g_epfd = epoll_create(nSize);
     85 
     86     epoll_event ev;
     87     ev.data.fd=g_listen_fd;
     88     ev.events = EPOLLIN | EPOLLET | EPOLLOUT;
     89     int nAddResult = epoll_ctl(g_epfd ,EPOLL_CTL_ADD, g_listen_fd ,&ev); //将新的fd添加到epoll的监听队列中
     90     if (nAddResult == -1)
     91     {
     92         printf ("epoll_ctl error\\n");
     93         return ;
     94     }
     95 
     96 
     97     while(true)
     98     {
     99         epoll_event events[nSize + 1];
    100         int nfds = epoll_wait(g_epfd, events, 20,0);
    101         for(int i=0; i<nfds; ++i)
    102         {
    103             printf("event num is:  %d\\n", nfds);
    104            if(events[i].data.fd == g_listen_fd) //有新的连接
    105            {
    106                sockaddr_in clientaddr;
    107                unsigned int clilen = sizeof(clientaddr);
    108                int connfd = accept(g_listen_fd, (sockaddr *)&clientaddr,  &clilen); //accept这个连接
    109                printf("new connection!  %d\\n", connfd);
    110 
    111                epoll_event event;
    112                event.data.fd=connfd;
    113                event.events = EPOLLIN | EPOLLET | EPOLLOUT | EPOLLHUP;
    114                epoll_ctl(g_epfd,EPOLL_CTL_ADD,connfd,&event); //将新的fd添加到epoll的监听队列中
    115 
    116                g_vecCLient.push_back(connfd);
    117            }
    118 
    119            else if( events[i].events & EPOLLIN ) //接收到数据,读socket
    120            {
    121                char szBuf[1024] = {0};
    122                int nRecvNum = recv(events[i].data.fd, szBuf, 1024, 0);   //读
    123 
    124 
    125                char szDest[1024] = {0};
    126                size_t nOutLen = 1024 ;
    127                GB2312ToUtf8(szBuf, nRecvNum, szDest, nOutLen);
    128                printf("recv size :%d, concent:%s\\n", nRecvNum, szBuf);
    129                printf("after conv  size :%d, concent:%s\\n", nOutLen ,  szDest);
    130 
    131                if(nRecvNum > 0)
    132                {
    133                    BoardCast(szBuf, nRecvNum);
    134                }
    135                else if(nRecvNum == -1)
    136                {
    137                    perror(NULL);
    138                    removeFd(events[i].data.fd);
    139                }
    140 
    141 //               ev.data.ptr = md;     //md为自定义类型,添加数据
    142 //               ev.events=EPOLLOUT|EPOLLET;
    143 //               epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改标识符,等待下一个循环时发送数据,异步处理的精髓
    144            }
    145            else if(events[i].events & EPOLLOUT) //有数据待发送,写socket
    146            {
    147                printf("EPOLLOUT\\n" );
    148 //               struct myepoll_data* md = (myepoll_data*)events[i].data.ptr;    //取数据
    149 //               sockfd = md->fd;
    150 //               send( sockfd, md->ptr, strlen((char*)md->ptr), 0 );        //发送数据
    151 //               ev.data.fd=sockfd;
    152 //               ev.events=EPOLLIN|EPOLLET;
    153 //               epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改标识符,等待下一个循环时接收数据
    154            }
    155            else if(events[i].events & EPOLLHUP) //socket disconnect
    156            {
    157                printf("socket disconnect socketid:%d\\n", events[i].data.fd);
    158                removeFd(events[i].data.fd);
    159            }
    160            else
    161            {
    162                //其他的处理
    163            }
    164         }
    165    }
    166 }
    167 
    168 void BoardCast(const char* msg, long int nLen)
    169 {
    170     for(citvecClient cit = g_vecCLient.begin(); cit != g_vecCLient.end(); cit++)
    171     {
    172         int nClientFd = *cit;
    173         int nSendLen = send(nClientFd, (const void* )msg ,  nLen, 0);
    174         printf("socket nSendLen:%d\\n", nSendLen);
    175     }
    176 
    177 }
    178 
    179 void removeFd(int fd)
    180 {
    181     epoll_ctl(g_epfd,EPOLL_CTL_DEL,fd, NULL); //delete socket in epoll
    182     for(itvecClient it = g_vecCLient.begin(); it != g_vecCLient.end(); it++)
    183     {
    184         if(fd == *it)
    185         {
    186             g_vecCLient.erase(it);
    187             return;
    188         }
    189     }
    190 }

 

2 Windows下的客户端代码  Windows、visual studio 、C++

 主线程  读线程  写线程

  1 #include "stdio.h"  
      2 #include <WinSock2.h>
      3 #include "cInitSock.h"
      4 #include <string>
      5 #pragma comment(lib,"WS2_32")
      6 
      7 
      8 using namespace std;
      9 //struct stMsg
     10 //{
     11 //    int        sCmdID;
     12 //    int        sLen;
     13 //    int        nValue;
     14 //    string    strContent;
     15 //
     16 //    stMsg()
     17 //    {
     18 //        sCmdID = 0;
     19 //        sLen = 0;
     20 //        nValue = 0;
     21 //        strContent = "";
     22 //    }
     23 //};
     24 
     25 
     26 
     27 char g_szIp[64] = "192.168.10.32";
     28 short  g_port = 8000;
     29 SOCKET g_sock;
     30 
     31 
     32 void ReadHandle();
     33 void WriteHandle();
     34 CRITICAL_SECTION g_cs;
     35 
     36 static int s_na = 0;
     37   
     38 
     39 void main()
     40 {
     41     cInitSock initSock;
     42     InitializeCriticalSection(&g_cs);
     43     g_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     44 
     45     sockaddr_in sockAddr;
     46     memset(&sockAddr,0,sizeof(sockAddr));
     47 
     48     sockAddr.sin_family = AF_INET;
     49     sockAddr.sin_addr.S_un.S_addr = inet_addr(g_szIp); 
     50     sockAddr.sin_port = htons((u_short)g_port);
     51     int nRestle = 0;
     52     nRestle= connect(g_sock, (sockaddr *)&sockAddr, sizeof(sockAddr) );
     53 
     54     DWORD dErr = GetLastError();
     55     if (nRestle != 0 )
     56     {
     57         printf("连接服务器失败 \\n");
     58         return;
     59     }
     60     printf("connect success \\n"); 
     61 
     62     int nReadThreadID;
     63     int nWriteThreadID;
     64     CreateThread(0, 0, (LPTHREAD_START_ROUTINE) ReadHandle, 0, 0, (LPDWORD)&nReadThreadID);
     65     CreateThread(0, 0, (LPTHREAD_START_ROUTINE) WriteHandle, 0, 0, (LPDWORD)&nWriteThreadID);
     66 
     67     printf("客户端开启成功\\n");
     68     while(1)
     69     {
     70         ;
     71     }
     72 
     73 }
     74 
     75 
     76 void ReadHandle()
     77 {
     78     char buf[1024] = "";
     79     int buflen = 0;
     80 
     81     while (1)
     82     {
     83         memset(buf, 0, 1024);
     84         buflen = recv(g_sock, buf, 1024, 0);  
     85         if ( buflen )
     86         {
     87             EnterCriticalSection((LPCRITICAL_SECTION)&g_cs);  
     88             printf("recv msg : %s,msgSiez:%d\\n", buf, buflen);
     89             LeaveCriticalSection((LPCRITICAL_SECTION)&g_cs);  
     90         } 
     91     } 
     92 }
     93 
     94 void WriteHandle()
     95 {
     96     char buf[1024] = "";
     97     int buflen = 0;
     98 
     99     while (1)
    100     {
    101         gets_s(buf);   
    102         //printf("the gets buf is:%s:end\\n", buf);
    103         buflen = send(g_sock, (const char* )&buf, strlen(buf), 0); 
    104         if ( buflen > 0)
    105         {
    106             EnterCriticalSection((LPCRITICAL_SECTION)&g_cs);  
    107             printf("send msg : %s,msgSiez:%d\\n", buf, buflen);
    108             LeaveCriticalSection((LPCRITICAL_SECTION)&g_cs);  
    109         }
    110         if (buflen == -1)
    111         {
    112             EnterCriticalSection((LPCRITICAL_SECTION)&g_cs);  
    113             printf("send msg error: %s\\n", buf);
    114             LeaveCriticalSection((LPCRITICAL_SECTION)&g_cs);  
    115         } 
    116     } 
    117 }
    118  

 

收藏
暂无回复