使用libev写服务器

libev官网:http://software.schmorp.de/pkg/libev.html

buffer.h

/*************************************************************************
    > File Name: buffer.h
    > Author: haha
    > Mail: [email protected] 
    > Created Time: Sun 25 Sep 2016 08:34:19 AM PDT
 ************************************************************************/

#include
#include
#include

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;
};


libev_server.cpp:


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "./libev/ev++.h"
#include "./libev/ev.h"
#include 
#include 
#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(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(this);
	write_io.set(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

你可能感兴趣的:(linux学习,c/c++)