一.服务器地址的相关初始化,如下:
void HighConcurrentServer::initServerAddr(){
std::string localAddr = "YOUR_SERVER_IP_ADDR";//这里要填写服务器IP地址,其他都是相关的socket编程的知识
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = ::inet_addr(localAddr.c_str());
serverAddr.sin_port = htons(SERV_PORT);
}
void HighConcurrentServer::createSocket(){
listenfd = socket(AF_INET, SOCK_STREAM, 0);
setnonblocking(listenfd);
epAdd(listenfd);
bind(listenfd, (sockaddr *)&serverAddr, sizeof(serverAddr));
listen(listenfd, MAX_CONNECTOR);
}
二.客户端连接事件的监听,如下:
void HighConcurrentServer::connectHandle(){
int n = -1;
n = epoll_wait(connfd, events, MAXEVENTS, 0);
int sockfd = 0;
socklen_t clilen;
for(int i=0;i<n;++i){
if(events[i].data.fd == listenfd){
printf("connectHandle()\n");
sockfd = accept(listenfd, (sockaddr *)&clientAddr, &clilen);
if(sockfd < 0){
printf("connfd < 0\n");
exit(1);
}
setnonblocking(sockfd);//设置为非阻塞
printf("sockfd->%d\n", sockfd);
char *str = inet_ntoa(clientAddr.sin_addr);
printf("connect from %s\n", str);
evt.data.fd = sockfd;
evt.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &evt);
}
}
}
说明:这里只是简单地示意了相关过程,没有写实际的业务处理,这个需要根据具体需要开发。
三.非阻塞函数的实现,如下:
void HighConcurrentServer::setnonblocking(int& sockfd) {
int flags = 0;
if (-1 == (flags = ::fcntl(sockfd, F_GETFL, 0))) {
printf("fcntl get flags failed\n");
exit(1);
}
if (-1 == ::fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) {
printf("fcntl set sockfd nonblock failed\n");
exit(1);
}
}
说明:相关函数的调用,简单明了,无需再详述。
四.接收客户端发送过来的数据,如下:
void HighConcurrentServer::readHandle(){
int n = -1;
n = epoll_wait(epfd, events, MAXEVENTS, 0);
int sockfd = 0;
socklen_t clilen;
for(int i=0;i<n;++i){
if (events[i].events & EPOLLIN) {
printf("readHandle()\n");
if ((sockfd = events[i].data.fd) < 0){
printf("something wrong must happen\n");
continue;
}
if ((n = read(sockfd, dataIn, DATALEN)) < 0) {//读取数据,存储在一个字符数组中,仅示意用,可以自己实现数据的全部读取,也可自己实现缓冲的大小
if (errno == ECONNRESET) {
close (sockfd);
events[i].data.fd = -1;
} else {
printf("readline error\n");
}
} else if (n = 0) {
close (sockfd);
events[i].data.fd = -1;
} else{
printf("recv msg is %s",dataIn);
}
evt.data.fd = sockfd;
evt.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &evt);//简单的把用户发过来的数据原样地发回给客户端
}
}
}
五.给客户端发送数据,如下:
void HighConcurrentServer::writeHandle(){
int n = -1;
n = epoll_wait(epfd, events, MAXEVENTS, 0);
int sockfd = 0;
socklen_t clilen;
for(int i=0;i<n;++i){
if (events[i].events & EPOLLOUT) {
printf("writeHandle()\n");
sockfd = events[i].data.fd;
write(sockfd, dataIn, DATALEN);
evt.data.fd = sockfd;
evt.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &evt);
}
}
}
源码部分就不上传了,需要的话,可以私下~
PS:初写文章,文笔生涩之处,各位请见谅,若有疑问或者交流的,可加本人YY号:301558660
转载请注明出处:山水间博客,http://blog.csdn.net/linyanwen99/article/details/8195839