基于libuv封装的TCP通信类-服务端类源代码

7320 人浏览 | 时间: 2016-04-01 19:42:51 | 作者: codexia 会员文章,禁止转载

代码运行环境:VS2010

libuv基本静态lib库和头文件:点此去下载libuv基本静态lib库和头文件

注意:项目一定要忽略导入库libcmt.lib,以免导出的标识符冲突。

基于libuv封装的TCP通信类-服务端类的代码:

头文件tcpServer.h:


#pragma once
/*---------------------------------------
- 文件  tcpServer.h
- 简介  基于libuv封装的tcp服务端的类
- 来源  C++技术网 http://www.cjjjs.com
- 作者  codexia (精简)
- 封装  phata(原始封装作者)
- 日期  2016-4-1
- 说明  在phata封装libuv库的基础上精简了不必要的代码,主要是日志,然后整理了排版,更符合C++排版风格,并将服务器端类和客户端分离为两个类
- lib   VS2010版的lib静态库的使用,项目中要忽略LIBCMT.lib,否则出现导出的符号重复
-----------------------------------------*/

#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Psapi.lib")
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment(lib,"Userenv.lib")
#pragma comment(lib,"libuv.lib")

#include "uv.h"
#include <string>
#include <map>
#include <stdio.h>
typedef void(*newconnect)(int clientid);
typedef void(*server_recvcb)(int cliendid, const char* buf, int bufsize);
#define BUFFERSIZE (1024*1024)
class clientdata;
class CTcpServer
{
public:
	CTcpServer(uv_loop_t* loop = uv_default_loop());
	virtual ~CTcpServer();

	static std::string GetUVError(int retcode)
	{
		std::string err;
		err = uv_err_name(retcode);
		err += ":";
		err += uv_strerror(retcode);
		return std::move(err);
	}

public:
	//基本函数
	bool Start(const char *ip, int port);//启动服务器,地址为IP4
	bool Start6(const char *ip, int port);//启动服务器,地址为IP6
	void close();

	bool setNoDelay(bool enable);
	bool setKeepAlive(int enable, unsigned int delay);

	const char* GetLastErrMsg() const {	return errmsg_.c_str();	};

	virtual int  send(int clientid, const char* data, std::size_t len);
	virtual void setnewconnectcb(newconnect cb);
	virtual void setrecvcb(int clientid, server_recvcb cb);//设置接收回调函数,每个客户端各有一个
protected:
	int GetAvailaClientID()const;//获取可用的client id
	bool DeleteClient(int clientid);//删除链表中的客户端
									//静态回调函数
	static void AfterServerRecv(uv_stream_t *client, ssize_t nread, const uv_buf_t* buf);
	static void AfterSend(uv_write_t *req, int status);
	static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
	static void AfterServerClose(uv_handle_t *handle);
	static void AfterClientClose(uv_handle_t *handle);
	static void acceptConnection(uv_stream_t *server, int status);

private:
	bool init();
	bool run(int status = UV_RUN_DEFAULT);
	bool bind(const char* ip, int port);
	bool bind6(const char* ip, int port);
	bool listen(int backlog = 1024);

	uv_tcp_t server_;//服务器链接
	std::map<int, clientdata*> clients_list_;//子客户端链接
	uv_mutex_t mutex_handle_;//保护clients_list_
	uv_loop_t *loop_;
	std::string errmsg_;
	newconnect newconcb_;
	bool isinit_;//是否已初始化,用于close函数中判断
};

class clientdata
{
public:
	clientdata(int clientid) :client_id(clientid), recvcb_(nullptr) {
		client_handle = (uv_tcp_t*)malloc(sizeof(*client_handle));
		client_handle->data = this;
		readbuffer = uv_buf_init((char*)malloc(BUFFERSIZE), BUFFERSIZE);
		writebuffer = uv_buf_init((char*)malloc(BUFFERSIZE), BUFFERSIZE);
	}
	virtual ~clientdata() {
		free(readbuffer.base);
		readbuffer.base = nullptr;
		readbuffer.len = 0;

		free(writebuffer.base);
		writebuffer.base = nullptr;
		writebuffer.len = 0;

		free(client_handle);
		client_handle = nullptr;
	}
	int client_id;//客户端id,惟一
	uv_tcp_t* client_handle;//客户端句柄
	CTcpServer* tcp_server;//服务器句柄(保存是因为某些回调函数需要到)
	uv_buf_t readbuffer;//接受数据的buf
	uv_buf_t writebuffer;//写数据的buf
	uv_write_t write_req;
	server_recvcb recvcb_;//接收数据回调给用户的函数
};
源文件tcpServer.cpp:



开通会员付1C币>>阅读全文
标注
评论
站内搜
百度搜
传送到手机
手机扫码,识别文字,完成传送x
加载中...
标注内容x
加载中...
添加标注x
收藏 3 点赞 1

相关阅读