您的位置:首页 > 理论基础 > 计算机网络

基于 TCP 的通讯接口(TCP Utils)

2016-07-25 14:40 423 查看
================================================================================

标题: 基于 TCP 的通讯接口(TCP Utils)

版本: 1.0.0.0

日期: 2016.07.25

--------------------------------------------------------------------------------

1. 概述

  可能很多人会说,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
3. TCPUtils 接口定义

  参见 <TCPUtils.h> 文件

// =======================================
// 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++ 类包装:

  参见 <TCPObjs.h> 文件

// =======================================
// 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 <string.h>
#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

  参见 <TCPObjs.cpp> 文件
</pre><pre name="code" class="cpp">// =======================================
// 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 压缩包中含有如下文件:

   ---------------------------------------------------------------

    \TCPUtils 1.0\_linux\demo\source-testtcp-centos6.5-i386.zip

    \TCPUtils 1.0\_linux\demo\source-testtcp-centos6.5-x64.zip

    \TCPUtils 1.0\_linux\exports\libtcputils32.so

    \TCPUtils 1.0\_linux\exports\libtcputils64.so

    \TCPUtils 1.0\_linux\test\testtcp-centos6.5-i386.zip

    \TCPUtils 1.0\_linux\test\testtcp-centos6.5-x64.zip

    \TCPUtils 1.0\classes\C&C++\TCPObjs.cpp

    \TCPUtils 1.0\classes\C&C++\TCPObjs.h

    \TCPUtils 1.0\classes\C&C++\TCPUtils.h

    \TCPUtils 1.0\classes\C&C++\TCPUtils32.lib

    \TCPUtils 1.0\classes\C&C++\TCPUtils64.lib

    \TCPUtils 1.0\classes\Delphi\TCPObjs.pas

    \TCPUtils 1.0\classes\Delphi\TCPUtils.pas

    \TCPUtils 1.0\demo\__lib32\kylib\ (KYLib for VC6)

    \TCPUtils 1.0\demo\__lib32\KYLib.lib

    \TCPUtils 1.0\demo\__lib32\KYLib_d.lib

    \TCPUtils 1.0\demo\__lib32\TCPUtils32.lib

    \TCPUtils 1.0\demo\__lib64\kylib\ (KYLib for VS2008)

    \TCPUtils 1.0\demo\__lib64\KYLib.lib

    \TCPUtils 1.0\demo\__lib64\KYLib_d.lib

    \TCPUtils 1.0\demo\__lib64\TCPUtils64.lib

    \TCPUtils 1.0\demo\TestTCP\release\TestClient.dat

    \TCPUtils 1.0\demo\TestTCP\release\TestClient.exe

    \TCPUtils 1.0\demo\TestTCP\release\TestClient.ini

    \TCPUtils 1.0\demo\TestTCP\release\TestServer.dat

    \TCPUtils 1.0\demo\TestTCP\release\TestServer.exe

    \TCPUtils 1.0\demo\TestTCP\release\TestServer.ini

    \TCPUtils 1.0\demo\TestTCP\release64\TestClient.exe

    \TCPUtils 1.0\demo\TestTCP\release64\TestServer.exe

    \TCPUtils 1.0\demo\TestTCP\units\TCPUtils.h

    \TCPUtils 1.0\demo\TestTCP\units\TestClient.cpp

    \TCPUtils 1.0\demo\TestTCP\units\TestServer.cpp

    \TCPUtils 1.0\demo\TestTCP\TestClient.dsp

    \TCPUtils 1.0\demo\TestTCP\TestClient.vcproj

    \TCPUtils 1.0\demo\TestTCP\TestServer.dsp

    \TCPUtils 1.0\demo\TestTCP\TestServer.vcproj

    \TCPUtils 1.0\demo\TestTCP\TestTCP.dsw

    \TCPUtils 1.0\demo\TestTCP\TestTCP.sln

    \TCPUtils 1.0\documents\TCPUtils.txt

    \TCPUtils 1.0\exports\TCPUtils32.dll

    \TCPUtils 1.0\exports\TCPUtils64.dll

    \TCPUtils 1.0\test\KYDbg32\DbgClient.bat

    \TCPUtils 1.0\test\KYDbg32\DbgServer.bat

    \TCPUtils 1.0\test\KYDbg32\KYDbg32.exe

    \TCPUtils 1.0\test\KYDbg32\KYDbg32.ini

    \TCPUtils 1.0\test\test-client\KYDbg32.exe

    \TCPUtils 1.0\test\test-client\KYDbg32.ini

    \TCPUtils 1.0\test\test-client\TCPUtils32.dll

    \TCPUtils 1.0\test\test-client\TestClient.dat

    \TCPUtils 1.0\test\test-client\TestClient.exe

    \TCPUtils 1.0\test\test-client\TestClient.ini

    \TCPUtils 1.0\test\test-server\KYDbg32.exe

    \TCPUtils 1.0\test\test-server\KYDbg32.ini

    \TCPUtils 1.0\test\test-server\TCPUtils32.dll

    \TCPUtils 1.0\test\test-server\TestServer.dat

    \TCPUtils 1.0\test\test-server\TestServer.exe

    \TCPUtils 1.0\test\test-server\TestServer.ini

   ---------------------------------------------------------------

================================================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  TCP 通讯