libevent 簡單客戶端和伺服器
阿新 • • 發佈:2019-01-02
server.cpp
#include <stdio.h> #include <string.h> #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <event.h> using namespace std; // 事件base struct event_base* base; // 讀事件回撥函式 void onRead(int iCliFd, short iEvent, void *arg) { int iLen; char buf[1500]; iLen = recv(iCliFd, buf, 1500, 0); if (iLen <= 0) { cout << "Client Close" << endl; // 連線結束(=0)或連線錯誤(<0),將事件刪除並釋放記憶體空間 struct event *pEvRead = (struct event*)arg; event_del(pEvRead); delete pEvRead; close(iCliFd); return; } buf[iLen] = 0; cout << "Client Info:" << buf << endl; struct bufferevent* buf_ev; buf_ev = bufferevent_new(iCliFd, NULL, NULL, NULL, NULL); buf_ev->wm_read.high = 4096; char MESSAGE[]="welcome to server.."; bufferevent_write(buf_ev, MESSAGE, strlen(MESSAGE)); } // 連線請求事件回撥函式 void onAccept(int iSvrFd, short iEvent, void *arg) { int iCliFd; struct sockaddr_in sCliAddr; socklen_t iSinSize = sizeof(sCliAddr); iCliFd = accept(iSvrFd, (struct sockaddr*)&sCliAddr, &iSinSize); // 連線註冊為新事件 (EV_PERSIST為事件觸發後不預設刪除) struct event *pEvRead = new event; event_set(pEvRead, iCliFd, EV_READ|EV_PERSIST, onRead, pEvRead); event_base_set(base, pEvRead); event_add(pEvRead, NULL); struct bufferevent* buf_ev; buf_ev = bufferevent_new(iCliFd, NULL, NULL, NULL, NULL); buf_ev->wm_read.high = 4096; char MESSAGE[]="welcome to server.."; bufferevent_write(buf_ev, MESSAGE, strlen(MESSAGE)); cout<<"a client connect:"<<iCliFd<<endl; } int main() { int iSvrFd; struct sockaddr_in sSvrAddr; memset(&sSvrAddr, 0, sizeof(sSvrAddr)); sSvrAddr.sin_family = AF_INET; sSvrAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sSvrAddr.sin_port = htons(8888); // 建立tcpSocket(iSvrFd),監聽本機8888埠 iSvrFd = socket(AF_INET, SOCK_STREAM, 0); bind(iSvrFd, (struct sockaddr*)&sSvrAddr, sizeof(sSvrAddr)); listen(iSvrFd, 10); // 初始化base base = (struct event_base*)event_init(); struct event evListen; // 設定事件 event_set(&evListen, iSvrFd, EV_READ|EV_PERSIST, onAccept, NULL); // 設定為base事件 event_base_set(base, &evListen); // 新增事件 event_add(&evListen, NULL); // 事件迴圈 event_base_dispatch(base); return 0; }
client.cpp
/******* 客戶端程式 client.c ************/ #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/types.h> #include <arpa/inet.h> #include<sys/time.h> #include<event.h> int main(int argc, char *argv[]) { int sockfd; char buffer[1024]; struct sockaddr_in server_addr; struct hostent *host; int portnumber,nbytes; if((host=gethostbyname("127.0.0.1"))==NULL) { fprintf(stderr,"Gethostname error\n"); exit(1); } if((portnumber=atoi("8888"))<0) { fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1); } /* 客戶程式開始建立 sockfd描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); exit(1); } /* 客戶程式填充服務端的資料 */ bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(portnumber); server_addr.sin_addr=*((struct in_addr *)host->h_addr); /* 客戶程式發起連線請求 */ if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) { fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); exit(1); } while(true) { char MESSAGE[]="hello server..\n"; //bufferevent_write(buf_ev,MESSAGE,strlen(MESSAGE)); // if(-1 == (::send(sockfd,MESSAGE,strlen(MESSAGE),0))) { printf("the net has a error occured.."); break; } if((nbytes = read(sockfd,buffer,1024))==-1) { fprintf(stderr,"read error:%s\n",strerror(errno)); exit(1); } buffer[nbytes]='\0'; printf("I have received:%s\n",buffer); memset(buffer,0,1024); sleep(2); } /* 結束通訊 */ close(sockfd); exit(0); }
編譯命令:
g++ -g server.cpp -o server -levent
g++ -g client.cpp -o client