废话不多数。先上代码。server.cpp
#include <jni.h>#include <string>#include <cmath>#include <sys/epoll.h>#include <iostream>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <errno.h>#include "androID/log.h"#include "jni.h"#include <pthread.h>struct epoll_event ev, events[20];#define ListENQ 20#define MAXliNE 5int main(int argc, char *argv[]) { int i, maxi, Listenfd, connfd, sockfd, myepfd, nfds, portnumber; ssize_t n; char line[MAXliNE]; socklen_t clilen; myepfd = epoll_create(58); portnumber = 8888; struct sockaddr_in clIEntaddr; struct sockaddr_in serveraddr; Listenfd = socket(AF_INET, SOCK_STREAM, 0); std::cout << "文件描述符为" + std::to_string(Listenfd) << std::endl; if (Listenfd < 0) { std::cout << "打开文件错误" + std::to_string(Listenfd) << std::endl; } ev.data.fd = Listenfd; //设置要处理的事件类型 ev.events = EPolliN | EPolLOUT; epoll_ctl(myepfd, EPolL_CTL_ADD, Listenfd, &ev); serveraddr.sin_family = AF_INET; char *local_addr = "10.6.25.153"; inet_aton(local_addr, &(serveraddr.sin_addr));//htons(portnumber); serveraddr.sin_port = htons(portnumber); bind(Listenfd, (sockaddr *) &serveraddr, sizeof(serveraddr)); Listen(Listenfd, ListENQ); for (;;) { //等待epoll事件的发生 int nfds = epoll_wait(myepfd, events, 20, -1); std::cout << "addr(obj2.pszTestStr) is: " + std::to_string(nfds) << std::endl; for (int i = 0; i < nfds; ++i) { if (events[i].data.fd == Listenfd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。 { connfd = accept(Listenfd, (sockaddr *) &clIEntaddr, &clilen); if (connfd < 0) { std::cout << "connfd<0" << std::endl; exit(1); } char *str = inet_ntoa(clIEntaddr.sin_addr); std::cout << "accapt a connection from " << str << std::endl; //设置用于读 *** 作的文件描述符 ev.data.fd = connfd; //设置用于注测的读 *** 作事件 ev.events = EPolliN | EPolLET; //注册ev epoll_ctl(myepfd, EPolL_CTL_ADD, connfd, &ev); } else if (events[i].events & EPolliN)//如果是已经连接的用户,并且收到数据,那么进行读入。 { std::cout << "EPolliN" << std::endl; if ((sockfd = events[i].data.fd) < 0) continue; if ((n = read(sockfd, line, MAXliNE)) < 0) { if (errno == ECONNreset) { close(sockfd); events[i].data.fd = -1; } else std::cout << "readline error" << std::endl; } else if (n == 0) { close(sockfd); events[i].data.fd = -1; } line[n] = '/0'; std::cout << "read " << line << std::endl; //设置用于写 *** 作的文件描述符 ev.data.fd = sockfd; //设置用于注测的写 *** 作事件 ev.events = EPolLOUT | EPolLET; //修改sockfd上要处理的事件为EPolLOUT epoll_ctl(myepfd, EPolL_CTL_MOD, sockfd, &ev); } else if (events[i].events & EPolLOUT) // 如果有数据发送 { sockfd = events[i].data.fd; write(sockfd, line, n); //设置用于读 *** 作的文件描述符 ev.data.fd = sockfd; //设置用于注测的读 *** 作事件 ev.events = EPolliN | EPolLET; //修改sockfd上要处理的事件为EPOliN epoll_ctl(myepfd, EPolL_CTL_MOD, sockfd, &ev); } } } return 0;}
以上为server的代码,我们现在把它编译为能够运行在androID手机上。这里要注意下。监听的ip要为自己手机的实际ip地址。可以通过ifconfig查看。如果用本机的“127.0.0.1”会监听不成功。利用androID studio的cmake编译系统能够方便的编译。这里我把我的cmakeList贴出来。
add_executable( server server.cpp)
另外app的build.gradle 文件中,配置支持c++。
externalNativeBuild { cmake { cppFlags "-std=c++11" } }
实际上主要就是这一句话。现在看下效果。
首先看下服务运行。注意server文件要不能拷贝到sdrcard这类目录运行,因为没有运行权限。
以上是内存溢出为你收集整理的Android上利用epoll机制实现手机服务器?全部内容,希望文章能够帮你解决Android上利用epoll机制实现手机服务器?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)