libev官网:http://software.schmorp.de/pkg/libev.html
buffer.h
/*************************************************************************
> File Name: buffer.h
> Author: haha
> Mail: haha@163.com
> Created Time: Sun 25 Sep 2016 08:34:19 AM PDT
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define default_buf_size 256
class Buffer
{
public:
Buffer()
{
buf = new char[default_buf_size];
buflen = default_buf_size;
}
~Buffer()
{
delete[] buf;
}
void set_write_buf_size(int needsize)
{
int buf_size = writeIdx + needsize;
if(buf_size <= buflen)
return;
if(needsize < readIdx)
{
memmove(buf, buf+readIdx, writeIdx-readIdx);
writeIdx -= readIdx;
readIdx = 0;
return;
}
while(buflen < buf_size)
buflen *= 2;
char *oldbuf = buf;
buf = new char[buflen];
memcpy(buf, oldbuf+readIdx, writeIdx-readIdx);
delete[] oldbuf;
writeIdx -= readIdx;
readIdx = 0;
}
int get_readable_size()
{
return writeIdx-readIdx;
}
int get_writeable_size()
{
return buflen-writeIdx;
}
void writebuf(void *data, int datalen)
{
set_write_buf_size(datalen);
memcpy(buf+writeIdx, data, datalen);
writeIdx += datalen;
}
int writeIdx;
int readIdx;
int buflen;
char *buf;
};
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdlib.h>
#include "./libev/ev++.h"
#include "./libev/ev.h"
#include <stdio.h>
#include <linux/tcp.h>
#include "buffer.h"
class NetServer{
public:
NetServer(){ sockfd = -1;}
~NetServer(){}
void start();
void accept_cb(ev::io &watcher, int revents);
void read_cb(ev::io &watcher, int revents);
void write_cb(ev::io &wather, int revents);
void timer_cb(ev::timer &watcher, int revents);
void Close();
private:
int sockfd;
ev::default_loop loop;
ev::io read_io;
ev::io write_io;
Buffer readbuf;
Buffer writebuf;
};
void NetServer::start()
{
sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(sockfd < 0)
{
perror("create socket error");
exit(0);
}
struct sockaddr_in sddr, cddr;
sddr.sin_family = AF_INET;
sddr.sin_addr.s_addr = INADDR_ANY;
sddr.sin_port = htons(8888);
if(bind(sockfd, (struct sockaddr*)&sddr, sizeof(sddr)) < 0)
{
perror("bind error");
exit(0);
}
if(listen(sockfd, 20)<0)
{
perror("listen error");
exit(0);
}
ev::io serv_io;
serv_io.set<NetServer, &NetServer::accept_cb>(this);
serv_io.start(sockfd, ev::READ);
std::cout << "server start now...\n";
loop.run(0);
}
void NetServer::accept_cb(ev::io &watcher, int revents)
{
struct sockaddr_in cddr;
socklen_t cli_len = sizeof(cddr);
int clifd = -1;
if(EV_ERROR & revents)
{
perror("get valid events");
return;
}
clifd = accept4(watcher.fd, (struct sockaddr*)&cddr, &cli_len, SOCK_NONBLOCK|SOCK_CLOEXEC);
if(clifd < 0)
return;
int one = 1;
setsockopt(clifd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one));
read_io.set<NetServer, &NetServer::read_cb>(this);
write_io.set<NetServer, &NetServer::write_cb>(this);
read_io.start(clifd, ev::READ);
write_io.start(clifd, ev::WRITE);
}
void NetServer::read_cb(ev::io &watcher, int revents)
{
readbuf.set_write_buf_size(1);
int readlen = recv(watcher.fd, readbuf.buf+readbuf.writeIdx, readbuf.get_writeable_size(), 0);
if(readlen < 0)
{
if(errno == EAGAIN || errno== EWOULDBLOCK)
return;
Close();
return;
}
if(readlen == 0)
{
Close();
return;
}
if(readlen > 0)
{
//if(readlen == len)
printf("recv buf:%s\n", readbuf.buf+readbuf.readIdx);
}
readbuf.readIdx += readlen;
}
void NetServer::write_cb(ev::io &watcher, int revents)
{
}
void NetServer::Close()
{
::close(sockfd);
sockfd = -1;
}
int main()
{
NetServer netServer;
netServer.start();
return 0;
}
编译:
注意:编译安装完libev之后,执行ldconfig
g++ -o libev_server libev_server.cpp -I/home/laijia/workfile/libev/ -L/usr/local/lib -lev