可能很多人会说,TCP 通讯相关接口和类库都很多,何必再造个轮子呢?话虽如此,但TCPUtils 并不同于其它接口,其简单易用,且通过配置就可以实现大容量连接,并且具有高并发性。在 CentOS 6.5 x64 服务器中,单个服务端可以稳定 20 多万个连接同时在线,且收发顺畅,这是经过实际使用及压力测试。
TCP 通讯接口是对 socket 进行包装,只负责接收和发送数据,不参与应用程序的协议解析。通讯接口对接收和发送线程进行管理,简化了socket接口调用的复杂度。在使用 TCP 通讯过程中,即使程序再小都要考虑收发和断开连接等等相关问题,无形中增加了 TCP 通讯程序的复杂度。
使用 TCPUtils 接口,开发人员只需要关心数据收发及连接断开后重连问题。特别是服务端程序,TCPUtils 帮助管理了客户连接,及连接受理和释放,简化了服务器程序难度。
TCPUtils 包含 Server, Connection 二大类型,其主要功能如下:
a. Server 主要负责端口侦听,以及 Connection 的受理分配和释放;
b. Connection 主要负责数据的收发及连接断开事件;
c. 可以创建/释放客户端的 Connection。
2. TCPUtils 下载
TCPUtils10.rar 下载地址: http://pan.baidu.com/s/1sl7vmC9
共享源码 sources 下载地址: http://pan.baidu.com/s/1i3ziOap
共享产品 products 下载地址: http://pan.baidu.com/s/130O9o
// =======================================
// Unit : 基于 TCP 的通讯接口
// Version: 1.0.0.0 (build 2016.07.24)
// Author : Kyee Ye
// Email : kyee_ye(at)126.com
// Copyright (C) Kyee workroom
// =======================================
#ifndef _TCPUtils_H_
#define _TCPUtils_H_
// 在 windows 下需要加载 lib 文件
#if defined(_WIN64)
#pragma comment(lib, "TCPUtils64.lib")
#elif defined(_WIN32)
#pragma comment(lib, "TCPUtils32.lib")
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Linux 下无 __stdcall/__cdecl 修饰符, 为了兼容 Windows 下修饰符 */
#ifdef __linux
// __stdcall 宏定义
#ifndef __stdcall
#define __stdcall
#endif
// __cdecl 宏定义
#ifndef __cdecl
#define __cdecl
#endif
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* 常量定义 */
// 返回值及错误码
enum TU_TTCPResult
{TU_trSuccess = 1, // 成功
TU_trFailure = 0, // 失败
TU_trUnknown = -1, // 未知错误
TU_trNotExist = -2, // 不存在(如: 连接对象)
TU_trNotConnect = -3, // 连接未打开
TU_trNonsupport = -4, // 不支持
TU_trVersion = -5, // 版本不兼容
TU_trTimeout = -6, // 操作超时
TU_trPassword = -7, // 密码错误
TU_trIsExisted = -8, // 已存在
TU_trIsRefused = -9, // 被拒绝
TU_trIsIllegal = -10, // 不合法
TU_trIsNullName = -11, // 名字为空
TU_trAttrInvalid = -12, // 属性无效
TU_trStateInvalid = -13, // 状态无效
TU_trHandleInvalid = -14, // 句柄无效
TU_trAccessIllegal = -15}; // 存取非法
// 接口的属性项
enum TU_TTCPAttrib
{TU_taVersion = 0, // 接口版本信息, 格式: "x.x.x.x (build yyyy.mm.dd)"
TU_taConnCount = 1, // 连接个数
TU_taServerCount = 2, // 服务端个数
TU_taSendThreads = 3, // 所有连接的发送线程最大个数, 默认值: 8
TU_taSendCacheSize = 4, // 所有连接的发送线程缓冲池尺寸, 默认值: 8
TU_taRecvThreads = 5, // 所有客户端的接收线程最大个数, 默认值: 8
TU_taRecvCacheSize = 6}; // 所有客户端的接收线程缓冲池尺寸, 默认值: 8
// 对象的状态
enum TU_TTCPObjState
{TU_tosInactive = 0, // 未打开
TU_tosClosing = 1, // 正在关闭
TU_tosOpening = 2, // 正在打开
TU_tosOpened = 3}; // 已打开
// 连接的类型
enum TU_TTCPConnType
{TU_tctUnknown = 0, // (未知)
TU_tctClient = 1, // TCP 客户端连接
TU_tctSrvClient = 2}; // TCP 服务端的客户连接
// 服务端的属性项
enum TU_TTCPServerAttrib
{TU_tsaOwner = -1, // 服务端所属对象(可以通过属性接口设置)
TU_tsaError = 0, // 打开服务失败返回的错误信息
TU_tsaState = 1, // 服务端的状态(TU_TTCPObjState)
TU_tsaLinger = 2, // TCP 句柄关闭后的拖延时长(秒), 默认值: 0
TU_tsaBindAddr = 3, // 服务端的绑定IP地址, 默认值: ""
TU_tsaBindPort = 4, // 服务端的侦听端口号, 默认值: 0
TU_tsaListenQueue = 5, // 服务端的侦听连接队列尺寸, 默认值: 256
TU_tsaRecvThreads = 6, // 接收线程最大个数, 默认值: 8
TU_tsaRecvCacheSize = 7, // 接收线程缓冲池尺寸, 默认值: 8
TU_tsaMaxClientCount = 8, // 服务端连接的最大客户端个数, 默认值: 0 表示无限制
TU_tsaSrvClientCount = 9, // 当前服务已连接的客户端个数
TU_tsaSendQueue = 10, // 连接的发送队列尺寸, 默认值: 64, 其中 0 表示无队列
TU_tsaKeepTimeout = 11, // 连接的心跳检测超时时间(单位: 毫秒), 默认值: 30000
TU_tsaKeepInterval = 12, // 连接的心跳检测重试间隔(单位: 毫秒), 默认值: 10000
TU_tsaKeepRetryTimes = 13, // 连接的心跳检测重试次数, 默认值: 3
// 回调事件属性, 取值范围: [32..63]
TU_tsaOnDisconnect = 32, // 服务的 OnDisconnect 事件, 断开侦听(TU_TTCPOnEvent)
TU_tsaOnAccept = 33, // 服务的 OnAccept 事件, 接受连接(TU_TTCPOnAccept), 可以设置连接属性
TU_tsaOnFreeClt = 34, // 服务的 OnFreeClt 事件, 释放连接(TU_TTCPOnEvent)
TU_tsaOnCltDisconnect= 35, // 连接的 OnCltDisconnect 事件, 断开连接(TU_TTCPOnEvent)
TU_tsaOnCltRecvEvent = 36}; // 连接的 OnCltRecvEvent 事件, 接收事件(TU_TTCPOnEvent)
// 连接的属性项
enum TU_TTCPConnAttrib
{TU_tcaOwner = -1, // 连接所属对象(可以通过属性接口设置)
TU_tcaError = 0, // 打开连接失败返回的错误信息(注: Type == TU_tctClient)
TU_tcaType = 1, // 连接的类型(TU_TTCPConnType)
TU_tcaState = 2, // 连接的状态(TU_TTCPObjState)
TU_tcaSrvObj = 3, // 连接的服务端对象(注: Type == TU_tctSrvClient)
TU_tcaLinger = 4, // 连接的句柄关闭后拖延时长(秒), 默认值: 0
TU_tcaTimeout = 5, // 连接的打开超时(单位: 毫秒), 默认值: 30000
TU_tcaPeerAddr = 6, // 连接的对端地址
TU_tcaPeerPort = 7, // 连接的对端端口号
TU_tcaCurrAddr = 8, // 连接的本地地址
TU_tcaCurrPort = 9, // 连接的本地端口号
TU_tcaLastTick = 10, // 连接的最后一次收发数据时 tick 值
TU_tcaSendQueue = 11, // 连接的发送队列尺寸, 默认值: 64, 其中 0 表示无队列
TU_tcaKeepTimeout = 12, // 连接的心跳检测超时时间(单位: 毫秒), 默认值: 30000
TU_tcaKeepInterval = 13, // 连接的心跳检测重试间隔(单位: 毫秒), 默认值: 10000
TU_tcaKeepRetryTimes = 14, // 连接的心跳检测重试次数, 默认值: 3
// 回调事件属性, 取值范围: [32..63]
TU_tcaOnDisconnect = 32, // 连接的 OnDisconnect 事件, 断开连接(TU_TTCPOnEvent)
TU_tcaOnRecvEvent = 33}; // 连接的 OnRecvEvent 事件, 接收事件(TU_TTCPOnEvent)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* 接口回调函数类型定义 */
// 对象事件的回调函数类型(如: OnRecvEvent, OnDisconnect, OnFreeClt 等等)
typedef void (__stdcall *TU_TTCPOnEvent)(void* AConnObj, void* AOwner);
// 服务端接受连接事件的回调函数类型(OnAccept)
// 注: 1. 服务端的客户连接对象 AConnObj 由 Server 创建和释放;
// 2. 若事件返回值 > 0 则表示接受连接, 否则拒绝连接;
// 3. 若服务端未设置 OnAccept 事件则无法打开服务端对象.
typedef long (__stdcall *TU_TTCPOnAccept)(void* ASrvObj, void* AConnObj);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef __cplusplus
extern "C"
{
#endif
/* 接口相关函数 */
// 接口初始化/释放函数
void __stdcall TCPInitialize();
void __stdcall TCPUninitialize();
// 接口版本信息, 格式: "x.x.x.x (build yyyy.mm.dd)"
// AVersion 返回版本号, 如: 0x0708090A 表示 7.8.9.10
char* __stdcall TCPGetVersion(long* AVersion);
// 取当前操作的最后错误码(注: 用于返回值非错误码的函数)
long __stdcall TCPGetLastError();
// 取接口属性
// 注: 返回值为属性值, ARetCode 为失败的返回码, 允许为空, 当字符串类型成功时为值尺寸
long __stdcall TCPGetInt(long Attrib, long* ARetCode/* = NULL*/);
void* __stdcall TCPGetObj(long Attrib, long* ARetCode/* = NULL*/);
char* __stdcall TCPGetStr(long Attrib, long* ARetCode/* = NULL*/);
// 设置接口属性
long __stdcall TCPSetInt(long Attrib, long AValue);
long __stdcall TCPSetObj(long Attrib, void* AValue);
long __stdcall TCPSetStr(long Attrib, const char* AValue, long ASize);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* 写 debug 信息到 KD 的相关函数 */
// 判断 Debug 是否已经打开
long __stdcall TCPDbgOpened();
// 写 Debug 行
void __stdcall TCPDbgWrite(const char* AInfo);
// 格式化写 Debug
void __cdecl TCPDbgWriteFmt(const char* AFormat, ...);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* TCP 服务端的相关函数 */
// 创建/释放 TCP 服务端
void* __stdcall TCPServerCreate();
void __stdcall TCPServerFree(void* ASrvObj);
// 打开/关闭 TCP 服务端
long __stdcall TCPServerOpen(void* ASrvObj);
long __stdcall TCPServerClose(void* ASrvObj);
// 取 TCP 服务端属性
// 注: 返回值为属性值, ARetCode 为失败的返回码, 允许为空, 当字符串类型成功时为值尺寸
long __stdcall TCPServerGetInt(void* ASrvObj, long Attrib, long* ARetCode/* = NULL*/);
void* __stdcall TCPServerGetObj(void* ASrvObj, long Attrib, long* ARetCode/* = NULL*/);
char* __stdcall TCPServerGetStr(void* ASrvObj, long Attrib, long* ARetCode/* = NULL*/);
// 设置 TCP 服务端属性
long __stdcall TCPServerSetInt(void* ASrvObj, long Attrib, long AValue);
long __stdcall TCPServerSetObj(void* ASrvObj, long Attrib, void* AValue);
long __stdcall TCPServerSetStr(void* ASrvObj, long Attrib,
const char* AValue, long ASize);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* 连接的相关函数 */
// 创建/释放 TCP 客户端, 返回连接对象
void* __stdcall TCPClientCreate();
void __stdcall TCPClientFree(void* AConnObj);
// 连接对象引用计数增/减 1
// 注: 1. 若 TCPConnIncRef 返回TU_trSuccess时, 则必须调用 TCPConnDecRef 减引用;
// 2. TCPConnDecRef 函数不检查 AConnObj 参数是否合法, 即 AConnObj 必须被函
// 数 TCPConnIncRef 成功加引用.
long __stdcall TCPConnIncRef(void* AConnObj);
void __stdcall TCPConnDecRef(void* AConnObj);
// 打开/关闭连接
long __stdcall TCPConnOpen(void* AConnObj);
long __stdcall TCPConnClose(void* AConnObj);
// 接收数据
// 注: 1. 为了函数性能不检查 AConnObj 参数是否合法, 即 AConnObj 必须存在;
// 2. 返回值为接收成功的数据尺寸, 若小于 0 则为错误码;
// 3. 此函数必须在 OnRecvEvent 事件中调用.
long __stdcall TCPConnRecv(void* AConnObj, void* AData, long ASize);
// 发送数据
// 注: 1. 为了函数性能不检查 AConnObj 参数是否合法, 即 AConnObj 必须存在;
// 2. 返回值为发送成功的数据尺寸, 若小于 0 则为错误码;
// 3. 若 SendQueue == 0 时, 则表示已加入发送缓冲区尺寸;
// 4. 否则数据优先加入发送缓冲区, 当缓冲区不够时则加入发送队列.
long __stdcall TCPConnSend(void* AConnObj, const void* AData, long ASize);
// 取连接属性
// 注: 返回值为属性值, ARetCode 为失败的返回码, 允许为空, 当字符串类型成功时为值尺寸
long __stdcall TCPConnGetInt(void* AConnObj, long Attrib, long* ARetCode/* = NULL*/);
void* __stdcall TCPConnGetObj(void* AConnObj, long Attrib, long* ARetCode/* = NULL*/);
char* __stdcall TCPConnGetStr(void* AConnObj, long Attrib, long* ARetCode/* = NULL*/);
// 设置连接属性
long __stdcall TCPConnSetInt(void* AConnObj, long Attrib, long AValue);
long __stdcall TCPConnSetObj(void* AConnObj, long Attrib, void* AValue);
long __stdcall TCPConnSetStr(void* AConnObj, long Attrib,
const char* AValue, long ASize);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
4. TCPUtils 接口 C++ 类包装:
参见
// =======================================
// Unit : TCPUtils objects
// Version: 1.0.0.0 (build 2016.09.02)
// Author : Kyee Ye
// Email : kyee_ye(at)126.com
// Copyright (C) Kyee workroom
// =======================================
#ifndef _TCPObjs_H_
#define _TCPObjs_H_
#include
#include "TCPUtils.h"
namespace TCPUtils
{
/* begin namespace */
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* TCP 相关的事件定义 */
class TTCPConnObj;
class TTCPServer;
// TObject - 空类
class TObject
{
};
// 连接事件
typedef void (TObject::*TDoConnEvent)(TTCPConnObj* AConnObj);
typedef struct
{
TDoConnEvent Method;
void* Object;
} TOnConnEvent;
// 接收数据事件
typedef void (TObject::*TDoRecvData)(TTCPConnObj* AConnObj, void* AData, long ASize);
typedef struct
{
TDoRecvData Method;
void* Object;
} TOnRecvData;
// 服务器事件
typedef void (TObject::*TDoSrvEvent)(TTCPServer* AServer);
typedef struct
{
TDoSrvEvent Method;
void* Object;
} TOnSrvEvent;
// 服务器接受连接事件
typedef void (TObject::*TDoAccept)(TTCPServer* AServer, TTCPConnObj* AConnObj,
bool& AIsRefused);
typedef struct
{
TDoAccept Method;
void* Object;
} TOnAccept;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* TTCPConnObj - TCP 连接对象类 */
class TTCPConnObj
{
public:
TTCPConnObj(void* AConnID = NULL);
virtual ~TTCPConnObj();
// 属性
void* Data() const { return FData; }
TTCPServer* Server() const { return FServer; }
void* ConnID() const { return FConnID; }
long ConnType() const { return FConnType; }// = TCPConnGetInt(FConnID, TU_tcaType, NULL);
char* Error() const { return TCPConnGetStr(FConnID, TU_tcaError, NULL); }
long State() const { return TCPConnGetInt(FConnID, TU_tcaState, NULL); }
long Timeout() const { return TCPConnGetInt(FConnID, TU_tcaTimeout, NULL); }
long SendQueue() const { return TCPConnGetInt(FConnID, TU_tcaSendQueue, NULL); }
char* CurrAddr() const { return TCPConnGetStr(FConnID, TU_tcaCurrAddr, NULL); }
long CurrPort() const { return TCPConnGetInt(FConnID, TU_tcaCurrPort, NULL); }
char* PeerAddr() const { return TCPConnGetStr(FConnID, TU_tcaPeerAddr, NULL); }
long PeerPort() const { return TCPConnGetInt(FConnID, TU_tcaPeerPort, NULL); }
long LastTick() const { return TCPConnGetInt(FConnID, TU_tcaLastTick, NULL); }
long KeepTimeout() const { return TCPConnGetInt(FConnID, TU_tcaKeepTimeout, NULL); }
long KeepInterval() const { return TCPConnGetInt(FConnID, TU_tcaKeepInterval, NULL); }
long KeepRetryTimes()const{ return TCPConnGetInt(FConnID, TU_tcaKeepRetryTimes, NULL); }
// 设置属性
void SetData(void* AData) { FData = AData; }
long SetTimeout(long ATimeout)
{ return TCPConnSetInt(FConnID, TU_tcaTimeout, ATimeout); }
long SetSendQueue(long AQueueSize)
{ return TCPConnSetInt(FConnID, TU_tcaSendQueue, AQueueSize); }
long SetCurrAddr(const char* Addr)
{ return TCPConnSetStr(FConnID, TU_tcaCurrAddr, Addr, (Addr != NULL) ? strlen(Addr) : 0); }
long SetCurrAddr(const char* Addr, long ALength)
{ return TCPConnSetStr(FConnID, TU_tcaCurrAddr, Addr, ALength); }
long SetCurrPort(long APort)
{ return TCPConnSetInt(FConnID, TU_tcaCurrPort, APort); }
long SetPeerAddr(const char* Addr)
{ return TCPConnSetStr(FConnID, TU_tcaPeerAddr, Addr, (Addr != NULL) ? strlen(Addr) : 0); }
long SetPeerAddr(const char* Addr, long ALength)
{ return TCPConnSetStr(FConnID, TU_tcaPeerAddr, Addr, ALength); }
long SetPeerPort(long APort)
{ return TCPConnSetInt(FConnID, TU_tcaPeerPort, APort); }
long SetKeepTimeout(long ATimeout)
{ return TCPConnSetInt(FConnID, TU_tcaKeepTimeout, ATimeout); }
long SetKeepInterval(long AInterval)
{ return TCPConnSetInt(FConnID, TU_tcaKeepInterval, AInterval); }
long SetKeepRetryTimes(long ARetryTimes)
{ return TCPConnSetInt(FConnID, TU_tcaKeepRetryTimes, ARetryTimes); }
// 打开/关闭连接
long Open() { return TCPConnOpen(FConnID); }
long Close() { return TCPConnClose(FConnID); }
// 发送数据
// 注: 1. 返回值为发送成功的数据尺寸, 若小于 0 则为错误码;
// 2. 若 SendQueue == 0 时, 则表示已加入发送缓冲区尺寸;
// 3. 否则数据优先加入发送缓冲区, 当缓冲区不够时则加入发送队列.
long Send(const void* AData, long ASize)
{ return TCPConnSend(FConnID, AData, ASize); }
// 设置事件
long SetOnRecvData(TDoRecvData AMethod, void* AObject);
long SetOnDisconnect(TDoConnEvent AMethod, void* AObject);
protected:
// 执行事件方法
void DoRecvData();
void DoDisconnect();
private:
void* FData; // 自定义数据
TTCPServer* FServer; // 连接所属的 TTCPServer 对象
void* FConnID; // TCP 连接 ID
long FConnType; // 连接类型
bool FNeedFree; // 是否需要释放
// 事件
TOnRecvData FOnRecvData; // 接收数据
TOnConnEvent FOnDisconnect; // 断开连接
private:
// 连接事件的回调函数
static void __stdcall _TCPOnDisconnect(void* AConnID, TTCPConnObj* AConnObj);
static void __stdcall _TCPOnRecvEvent(void* AConnID, TTCPConnObj* AConnObj);
private:
friend class TTCPServer;
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* TTCPServer - TCP 服务器类 */
class TTCPServer
{
public:
TTCPServer();
virtual ~TTCPServer();
// 属性
void* Data() const { return FData; }
void* SrvID() const { return FSrvID; }
long State() const { return TCPServerGetInt(FSrvID, TU_tsaState, NULL); }
char* Error() const { return TCPServerGetStr(FSrvID, TU_tsaError, NULL); }
char* Addr() const { return TCPServerGetStr(FSrvID, TU_tsaBindAddr, NULL); }
long Port() const { return TCPServerGetInt(FSrvID, TU_tsaBindPort, NULL); }
long Linger() const { return TCPServerGetInt(FSrvID, TU_tsaLinger, NULL); }
long SendQueue() const { return TCPServerGetInt(FSrvID, TU_tsaSendQueue, NULL); }
long ListenQueue() const { return TCPServerGetInt(FSrvID, TU_tsaListenQueue, NULL); }
long RecvThreads() const { return TCPServerGetInt(FSrvID, TU_tsaRecvThreads, NULL); }
long CacheThreads() const { return TCPServerGetInt(FSrvID, TU_tsaRecvCacheSize, NULL); }
long MaxClients() const { return TCPServerGetInt(FSrvID, TU_tsaMaxClientCount, NULL); }
long ClientCount() const { return TCPServerGetInt(FSrvID, TU_tsaSrvClientCount, NULL); }
long KeepTimeout() const { return TCPServerGetInt(FSrvID, TU_tsaKeepTimeout, NULL); }
long KeepInterval() const { return TCPServerGetInt(FSrvID, TU_tsaKeepInterval, NULL); }
long KeepRetryTimes()const{ return TCPServerGetInt(FSrvID, TU_tsaKeepRetryTimes, NULL); }
// 设置属性
void SetData(void* AData) { FData = AData; }
long SetAddr(const char* Addr)
{ return TCPServerSetStr(FSrvID, TU_tsaBindAddr, Addr, (Addr != NULL) ? strlen(Addr) : 0); }
long SetAddr(const char* Addr, long ALength)
{ return TCPServerSetStr(FSrvID, TU_tsaBindAddr, Addr, ALength); }
long SetPort(long APort)
{ return TCPServerSetInt(FSrvID, TU_tsaBindPort, APort); }
long SetLinger(long ALinger)
{ return TCPServerSetInt(FSrvID, TU_tsaLinger, ALinger); }
long SetSendQueue(long AQueueSize)
{ return TCPServerSetInt(FSrvID, TU_tsaSendQueue, AQueueSize); }
long SetListenQueue(long AListenQueue)
{ return TCPServerSetInt(FSrvID, TU_tsaListenQueue, AListenQueue); }
long SetRecvThreads(long ACount)
{ return TCPServerSetInt(FSrvID, TU_tsaRecvThreads, ACount); }
long SetCacheThreads(long ACount)
{ return TCPServerSetInt(FSrvID, TU_tsaRecvCacheSize, ACount); }
long SetMaxClients(long AMaxCount)
{ return TCPServerSetInt(FSrvID, TU_tsaMaxClientCount, AMaxCount); }
long SetKeepTimeout(long ATimeout)
{ return TCPServerSetInt(FSrvID, TU_tsaKeepTimeout, ATimeout); }
long SetKeepInterval(long AInterval)
{ return TCPServerSetInt(FSrvID, TU_tsaKeepInterval, AInterval); }
long SetKeepRetryTimes(long ARetryTimes)
{ return TCPServerSetInt(FSrvID, TU_tsaKeepRetryTimes, ARetryTimes); }
// 打开/关闭 TCP 服务端
long Open() { return TCPServerOpen(FSrvID); }
long Close() { return TCPServerClose(FSrvID); }
// 设置事件
long SetOnDisconnect(TDoSrvEvent AMethod, void* AObject);
long SetOnAccept(TDoAccept AMethod, void* AObject);
long SetOnFreeClt(TDoConnEvent AMethod, void* AObject);
long SetOnCltRecvData(TDoRecvData AMethod, void* AObject);
protected:
// 执行事件方法
void DoDisconnect();
void DoAccept(TTCPConnObj* AConnObj, bool& AIsRefused);
void DoFreeClt(TTCPConnObj* AConnObj);
private:
void* FData; // 自定义数据
void* FSrvID; // 服务器 ID
// 事件
TOnSrvEvent FOnDisconnect; // 断开侦听
TOnAccept FOnAccept; // 接受连接
TOnConnEvent FOnFreeClt; // 释放连接
TOnRecvData FOnCltRecvData; // 接收数据
private:
// 服务器事件的回调函数
static void __stdcall _SrvOnDisconnect(void* ASrvID, TTCPServer* AServer);
static long __stdcall _SrvOnAccept(void* ASrvID, void* AConnID);
static void __stdcall _SrvOnFreeClt(void* AConnID, TTCPConnObj* AConnObj);
};
/* end namespace */
}
#endif
// ======================================= // Unit : TCPUtils objects // Version: 1.0.0.0 (build 2016.09.02) // Author : Kyee Ye // Email : kyee_ye(at)126.com // Copyright (C) Kyee workroom // ======================================= #include "TCPObjs.h" namespace TCPUtils { /* begin namespace */ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* TTCPConnObj - TCP 连接对象类 */ // ---------------- 静态函数 ---------------- // 连接的 OnDisconnect 回调事件 void __stdcall TTCPConnObj::_TCPOnDisconnect(void* AConnID, TTCPConnObj* AConnObj) { AConnObj->DoDisconnect(); } // 连接的 OnRecvData 回调事件 void __stdcall TTCPConnObj::_TCPOnRecvEvent(void* AConnID, TTCPConnObj* AConnObj) { AConnObj->DoRecvData(); } // ---------------- 构造函数和析构函数 ---------------- // 构造函数 TTCPConnObj::TTCPConnObj(void* AConnID) { // 初始化 FData = NULL; FServer = NULL; FConnID = NULL; FConnType = TU_tctUnknown; FNeedFree = false; // 初始化事件 FOnRecvData.Method = NULL; FOnRecvData.Object = NULL; FOnDisconnect.Method = NULL; FOnDisconnect.Object = NULL; // 设置对象关联 if (AConnID == NULL) { FConnID = TCPClientCreate(); if (FConnID != NULL) { FNeedFree = true; FConnType = TU_tctClient; TCPConnSetObj(FConnID, TU_tcaOwner, this); } } else if (TCPConnIncRef(AConnID) == TU_trSuccess) { FConnID = AConnID; FConnType = TCPConnGetInt(AConnID, TU_tcaType, NULL); TCPConnSetObj(FConnID, TU_tcaOwner, this); } } // 析构函数 TTCPConnObj::~TTCPConnObj() { // 置空 void* pConn = FConnID; FConnID = NULL; // 判断是否非空 if (pConn != NULL) { // 关闭连接 TCPConnClose(pConn); // 清空数据 if (TCPConnGetObj(pConn, TU_tcaOwner, NULL) == this) TCPConnSetObj(pConn, TU_tcaOwner, NULL); // 释放连接 if (FNeedFree) TCPClientFree(pConn); else TCPConnDecRef(pConn); } } // ---------------- 私有函数 ---------------- // 激发 OnDisconnect 事件 void TTCPConnObj::DoDisconnect() { if (FOnDisconnect.Method != NULL) try { ((TObject*)FOnDisconnect.Object->*FOnDisconnect.Method)(this); } catch (...) {} } // 激发 OnRecvData 事件 void TTCPConnObj::DoRecvData() { // 接收数据 char arrData[8192]; long intSize = TCPConnRecv(FConnID, arrData, sizeof(arrData)); // 激发事件 if ((intSize > 0) && (FOnRecvData.Method != NULL)) try { ((TObject*)FOnRecvData.Object->*FOnRecvData.Method)(this, arrData, intSize); } catch (...) {} } // ---------------- 公有函数 ---------------- // 设置 OnRecvData 事件 long TTCPConnObj::SetOnRecvData(TDoRecvData AMethod, void* AObject) { // 初始化 long result = TU_trUnknown; // 检查参数 if (FConnID != NULL) { void* pFunc = (AMethod != NULL) ? &TTCPConnObj::_TCPOnRecvEvent : NULL; result = TCPConnSetObj(FConnID, TU_tcaOnRecvEvent, pFunc); if (result != TU_trSuccess) ; else if (AMethod != NULL) { FOnRecvData.Object = AObject; FOnRecvData.Method = AMethod; } else { FOnRecvData.Method = NULL; FOnRecvData.Object = NULL; } } // 返回结果 return result; } // 设置 OnDisconnect 事件 long TTCPConnObj::SetOnDisconnect(TDoConnEvent AMethod, void* AObject) { // 初始化 long result = TU_trUnknown; // 检查参数 if (FConnID != NULL) { void* pFunc = (AMethod != NULL) ? &TTCPConnObj::_TCPOnDisconnect : NULL; result = TCPConnSetObj(FConnID, TU_tcaOnDisconnect, pFunc); if (result != TU_trSuccess) ; else if (AMethod != NULL) { FOnDisconnect.Object = AObject; FOnDisconnect.Method = AMethod; } else { FOnDisconnect.Method = NULL; FOnDisconnect.Object = NULL; } } // 返回结果 return result; } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* TTCPServer - TCP 服务器类 */ // ---------------- 静态成员 ---------------- // ---------------- 静态函数 ---------------- // 服务的 OnDisconnect 回调事件 void __stdcall TTCPServer::_SrvOnDisconnect(void* ASrvID, TTCPServer* AServer) { AServer->DoDisconnect(); } // 服务的 OnAccept 回调事件 long __stdcall TTCPServer::_SrvOnAccept(void* ASrvID, void* AConnID) { // 初始化 long result = -1; bool boolRefused = true; // 取服务对象 TTCPServer* objSrv = (TTCPServer*)TCPServerGetObj(ASrvID, TU_tsaOwner, NULL); if (objSrv != NULL) { TTCPConnObj* objConn = new TTCPConnObj(AConnID); if (objConn != NULL) { // 激发 OnAccept 事件 try { objSrv->DoAccept(objConn, boolRefused); result = 0; } catch (...) {} // 判断是否拒绝 if (boolRefused) delete objConn; else result = 1; } } // 返回结果 return result; } // 服务的 OnFreeClt 回调事件 void __stdcall TTCPServer::_SrvOnFreeClt(void* AConnID, TTCPConnObj* AConnObj) { // 激发 OnFreeClt 事件 try { TTCPServer* objSrv = AConnObj->Server(); if (objSrv != NULL) objSrv->DoFreeClt(AConnObj); } catch (...) {} // 释放对象 delete AConnObj; } // ---------------- 构造函数和析构函数 ---------------- // 构造函数 TTCPServer::TTCPServer() { // 初始化 FData = NULL; FOnDisconnect.Method = NULL; FOnDisconnect.Object = NULL; FOnAccept.Method = NULL; FOnAccept.Object = NULL; FOnFreeClt.Method = NULL; FOnFreeClt.Object = NULL; FOnCltRecvData.Method = NULL; FOnCltRecvData.Object = NULL; // 创建 TCP 服务端对象, 并设置关联 FSrvID = TCPServerCreate(); if (FSrvID != NULL) TCPServerSetObj(FSrvID, TU_tsaOwner, this); } // 析构函数 TTCPServer::~TTCPServer() { // 判断是否非空 if (FSrvID != NULL) { // 关闭 TCPServerClose(FSrvID); // 清除关联 TCPServerSetObj(FSrvID, TU_tsaOwner, NULL); // 释放对象 TCPServerFree(FSrvID); } } // ---------------- 私有函数 ---------------- // ---------------- 保护函数 ---------------- // 激发 OnDisconnect 事件 void TTCPServer::DoDisconnect() { if (FOnDisconnect.Method != NULL) try { ((TObject*)FOnDisconnect.Object->*FOnDisconnect.Method)(this); } catch (...) {} } // 激发 OnAccept 事件 void TTCPServer::DoAccept(TTCPConnObj* AConnObj, bool& AIsRefused) { AIsRefused = true; if (FOnAccept.Method != NULL) try { AConnObj->FServer = this; AConnObj->FOnRecvData = FOnCltRecvData; ((TObject*)FOnAccept.Object->*FOnAccept.Method)(this, AConnObj, AIsRefused); } catch (...) {} } // 激发 OnFreeClt 事件 void TTCPServer::DoFreeClt(TTCPConnObj* AConnObj) { if (FOnFreeClt.Method != NULL) try { ((TObject*)FOnFreeClt.Object->*FOnFreeClt.Method)(AConnObj); } catch (...) {} } // ---------------- 公有函数 ---------------- // 设置 OnDisconnect 事件 long TTCPServer::SetOnDisconnect(TDoSrvEvent AMethod, void* AObject) { // 初始化 long result = TU_trUnknown; // 检查参数 if (FSrvID != NULL) { void* pFunc = (AMethod != NULL) ? &TTCPServer::_SrvOnDisconnect : NULL; result = TCPServerSetObj(FSrvID, TU_tsaOnDisconnect, pFunc); if (result != TU_trSuccess) ; else if (AMethod != NULL) { FOnDisconnect.Object = AObject; FOnDisconnect.Method = AMethod; } else { FOnDisconnect.Method = NULL; FOnDisconnect.Object = NULL; } } // 返回结果 return result; } // 设置 OnAccept 事件 long TTCPServer::SetOnAccept(TDoAccept AMethod, void* AObject) { // 初始化 long result = TU_trUnknown; // 检查参数 if (FSrvID != NULL) { void* pFunc = (AMethod != NULL) ? &TTCPServer::_SrvOnAccept : NULL; result = TCPServerSetObj(FSrvID, TU_tsaOnAccept, pFunc); if (result != TU_trSuccess) ; else if (AMethod != NULL) { FOnAccept.Object = AObject; FOnAccept.Method = AMethod; } else { FOnAccept.Method = NULL; FOnAccept.Object = NULL; } } // 返回结果 return result; } // 设置 OnFreeClt 事件 long TTCPServer::SetOnFreeClt(TDoConnEvent AMethod, void* AObject) { // 初始化 long result = TU_trUnknown; // 检查参数 if (FSrvID != NULL) { void* pFunc = (AMethod != NULL) ? &TTCPServer::_SrvOnFreeClt : NULL; result = TCPServerSetObj(FSrvID, TU_tsaOnFreeClt, pFunc); if (result != TU_trSuccess) ; else if (AMethod != NULL) { FOnFreeClt.Object = AObject; FOnFreeClt.Method = AMethod; } else { FOnFreeClt.Method = NULL; FOnFreeClt.Object = NULL; } } // 返回结果 return result; } // 设置 OnCltRecvData 事件 long TTCPServer::SetOnCltRecvData(TDoRecvData AMethod, void* AObject) { // 初始化 long result = TU_trUnknown; // 检查参数 if (FSrvID != NULL) { void* pFunc = (AMethod != NULL) ? &TTCPConnObj::_TCPOnRecvEvent : NULL; result = TCPServerSetObj(FSrvID, TU_tsaOnCltRecvEvent, pFunc); if (result != TU_trSuccess) ; else if (AMethod != NULL) { FOnCltRecvData.Object = AObject; FOnCltRecvData.Method = AMethod; } else { FOnCltRecvData.Method = NULL; FOnCltRecvData.Object = NULL; } } // 返回结果 return result; } /* end namespace */ }
5. TCPUtils 压缩包中含有如下文件:
---------------------------------------------------------------