C++Builder中调用hp-sokcet网络通信库

在C++Builder中调用hp-socket函数库方法如下:

(1)从hp-socket-5.4.4目录中复制出DLL和lib,路径如下:
hp-socket-5.4.4\hp-socket-5.4.4\Windows\Bin\HPSocket4C\x86\HPSocket4C.dll
hp-socket-5.4.4\hp-socket-5.4.4\Windows\Bin\HPSocket4C\x86\HPSocket4C.lib
(2)利用C++Builder提供的工具,将VC版的导入库转为C++Builder支持的导入库.如下:
coff2omf -lib:ms c:/HPSocket4C.lib bcb c:/HPSocket4CB.lib
(3)包含HPSokcet4C.h头文件,文件所在路径如下:
hp-socket-5.4.4\hp-socket-5.4.4\Windows\Src

只能以函数的方式调用HPSocket4C.dll中的功能,虽然作者提供了一个类,但是由于兼容性,编译不能通过.

#include "HPSocket4C.h"
#include "globalUnit.h"
#include <Forms.hpp>
#pragma comment(lib,HPSocket4CB.lib)
class TGpsServer
{
public:
        static  HWND    m_hWnd;
        char    m_szIP[20];
        int     PORT;

	TGpsServer();
	~TGpsServer();

	HP_TcpPullServer         m_pServer;  //创建服务器
	HP_TcpPullServerListener m_pListener;//监听器

private:
	//回调函数
       static	En_HP_HandleResult __stdcall OnPrepareListen(HP_Server pSender, unsigned int  soListen);
       static   En_HP_HandleResult __stdcall OnAccept(HP_Server pSender, HP_CONNID dwConnID, unsigned int  soClient);
       static	En_HP_HandleResult __stdcall OnSend(HP_Server pSender, HP_CONNID dwConnID,const BYTE*  pData, int iLength);
       static	En_HP_HandleResult __stdcall OnReceive(HP_Server pSender, HP_CONNID dwConnID, int iLength);
       static	En_HP_HandleResult __stdcall OnClose(HP_Server pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode);
       static	En_HP_HandleResult __stdcall OnShutdown(HP_Server pSender);
public:
       VOID  StartServer(HWND  hWnd);
       VOID  StopServer();

       static  STExtraData* FindExtraData(HP_Server pSender, HP_CONNID dwConnID);
       static  void  RemoveExtraData(HP_Server pSender, HP_CONNID dwConnID);

private:
       static BOOL  m_ServerStart;
};
//静态成员变量初始化
BOOL TGpsServer::m_ServerStart = FALSE;
HWND TGpsServer::m_hWnd = NULL;
#endif

以上是自定义类的.h文件(其中STExtraData为自定义的结构体,用来传递附加数据).cpp文件内容如下:

#pragma hdrstop
#include "HpSocketUnit.h"
#include <stdio.h>
#include <utilcls.h>
#include <assert.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
TGpsServer::TGpsServer()
{
    // 创建监听器对象
    m_pListener = ::Create_HP_TcpPullServerListener();
    // 创建 Socket 对象
    m_pServer = ::Create_HP_TcpPullServer(m_pListener);
    // 设置 Socket 监听器回调函数

    ::HP_Set_FN_Server_OnPrepareListen(m_pListener, OnPrepareListen);
    ::HP_Set_FN_Server_OnAccept(m_pListener, OnAccept);
    ::HP_Set_FN_Server_OnSend(m_pListener, OnSend);
    ::HP_Set_FN_Server_OnPullReceive(m_pListener, OnReceive);
    ::HP_Set_FN_Server_OnClose(m_pListener, OnClose);
    ::HP_Set_FN_Server_OnShutdown(m_pListener, OnShutdown);
}

TGpsServer::~TGpsServer()
{
    // 销毁 Socket 对象
    ::Destroy_HP_TcpPullServer(m_pServer);
    // 销毁监听器对象
    ::Destroy_HP_TcpPullServerListener(m_pListener);
}

En_HP_HandleResult __stdcall TGpsServer::OnPrepareListen(HP_Server pSender, unsigned int  soListen)
{
    setlocale(LC_ALL, "chs");
    TCHAR szAddress[50];
    int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
    USHORT usPort;

    ::HP_Server_GetListenAddress(pSender, szAddress, &iAddressLen, &usPort);

    return HR_OK;
}

En_HP_HandleResult __stdcall TGpsServer::OnAccept(HP_Server pSender, HP_CONNID dwConnID, unsigned int  soClient)
{
    BOOL bPass = TRUE;
    TCHAR szAddress[50];
    int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
    USHORT usPort;

    ::HP_Server_GetRemoteAddress(pSender, dwConnID, szAddress, &iAddressLen, &usPort);

    char buff[100] = {0};
    sprintf(buff,"接入客户端[ID=%d]:IP=%s,端口=%d",dwConnID, szAddress, usPort);
    strcpy(g_szBuff,buff);

    SendMessage(m_hWnd,WM_MAINFORM_SHOW,0,0);
    SendMessage(m_hWnd,WM_MAINFORM_SHOW,0,4);

    STExtraData * pStExtraData = new STExtraData;
    pStExtraData->ConnID = dwConnID;
    strcpy(pStExtraData->szIP,szAddress);
    pStExtraData->nPort = usPort;
    if(bPass = HP_Server_SetConnectionExtra(pSender,dwConnID, pStExtraData))
       return bPass ? HR_OK : HR_ERROR;
}

En_HP_HandleResult __stdcall TGpsServer::OnSend(HP_Server pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength)
{
    return HR_OK;
}

En_HP_HandleResult __stdcall TGpsServer::OnReceive(HP_Server pSender, HP_CONNID dwConnID, int iLength)
{
    STExtraData * pStExtraData = FindExtraData(pSender,dwConnID);
    
    AnsiString strTemp = AnsiString().sprintf("接收客户端数据包[ID=%d],数据长度=%d,IP=%s,Port=%d",
            dwConnID,iLength,pStExtraData->szIP,pStExtraData->nPort);
    strcpy(g_szBuff,strTemp.c_str());

    SendMessage(m_hWnd,WM_MAINFORM_SHOW,0,0);

    HP_TcpPullServer_Fetch(pSender,dwConnID,g_szBuff,iLength);

    SendMessage(m_hWnd,WM_MAINFORM_SHOW,iLength,3);

    return HR_OK;
}

En_HP_HandleResult __stdcall TGpsServer::OnClose(HP_Server pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode)
{
    AnsiString strTemp;
    if(iErrorCode == SE_OK)
        strTemp = AnsiString().sprintf("客户端[ID=%d]正常退出",dwConnID);
    else
        strTemp = AnsiString().sprintf("客户端[ID=%d]发生错误:操作码%d,错误码%d",dwConnID,enOperation,iErrorCode);

    strcpy(g_szBuff,strTemp.c_str());
    SendMessage(m_hWnd,WM_MAINFORM_SHOW,0,0);
    SendMessage(m_hWnd,WM_MAINFORM_SHOW,0,4);

    RemoveExtraData(pSender,dwConnID);
    
    return HR_OK;
}

En_HP_HandleResult __stdcall TGpsServer::OnShutdown(HP_Server pSender)
{
    AnsiString strTemp = "服务器关闭";
    strcpy(g_szBuff,strTemp.c_str());
    PostMessage(m_hWnd,WM_MAINFORM_SHOW,0,0);
    PostMessage(m_hWnd,WM_MAINFORM_SHOW,0,2);

    return HR_OK;
}

VOID TGpsServer::StartServer(HWND   hWnd)
{//启动服务器
    m_hWnd = hWnd;
    
    if (!HP_Server_Start(m_pServer, "0.0.0.0", PORT))
    {
        m_ServerStart = FALSE;
        OLETRACE("服务器启动出错:%d,%s", ::HP_Server_GetLastError(m_pServer),
             ::HP_Server_GetLastErrorDesc(m_pServer));
        AnsiString strTemp;
        strTemp.sprintf("服务器启动出错:%d,%s", ::HP_Server_GetLastError(m_pServer),
             ::HP_Server_GetLastErrorDesc(m_pServer));
        strcpy(g_szBuff,"服务器启动,绑定0.0.0.0:7890!");
        PostMessage(m_hWnd,WM_MAINFORM_SHOW,0,0);
    }
    else
    {
        m_ServerStart = TRUE;
        strcpy(g_szBuff,"服务器启动,绑定0.0.0.0:7890!");
        PostMessage(m_hWnd,WM_MAINFORM_SHOW,0,0);
        PostMessage(m_hWnd,WM_MAINFORM_SHOW,0,1);
    }
}

VOID TGpsServer::StopServer()
{//停止服务器
    ::HP_Server_Stop(m_pServer);
    m_ServerStart = FALSE;
}

STExtraData* TGpsServer::FindExtraData(HP_Server pSender,HP_CONNID dwConnID)
{
    PVOID pInfo = NULL;

    bool ret = HP_Server_GetConnectionExtra(pSender,dwConnID, &pInfo);

    return (STExtraData*)pInfo;
}

void TGpsServer::RemoveExtraData(HP_Server pSender,HP_CONNID dwConnID)
{
    STExtraData* pInfo = FindExtraData(pSender, dwConnID);
    assert(pInfo != NULL);

    delete pInfo;
}

上述代码参考了作者的 C#、VC2015 的代码,改写后,可以正常运行,效果很好。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
========================================================================================== v3.0.2 更新: ========================================================================================== > 把 HP-Socket 编译为动态链接: ----------------- 1、应用程序可以通过导入源代码或动态链接方式使用 HP-Socket 2、动态链接使用方法 方法一: ----------------------------------------------------------------------- (0) 应用程序包含 SocketInterface.h 和 HPSocket.h 头文件 (1) 调用 HP_Create_Xxx() 函数创建 HPSocket 对象 (2) 使用完毕后调用 HP_Destroy_Xxx() 函数销毁 HPSocket 对象 方法二: ----------------------------------------------------------------------- (0) 应用程序包含 SocketInterface.h 和 HPSocket.h 头文件 (1) 创建 CXxxWrapper 包装器,通过包装器智能指针使用 HPSocket 对象 3、动态链接发行版本 (1) Bin/x86/HPSocket.dll - (32位/MBCS/Release) (2) Bin/x86/HPSocket_D.dll - (32位/MBCS/DeBug) (3) Bin/x86/HPSocket_U.dll - (32位/UNICODE/Release) (4) Bin/x86/HPSocket_UD.dll - (32位/UNICODE/DeBug) (5) Bin/x64/HPSocket.dll - (64位/MBCS/Release) (6) Bin/x64/HPSocket_D.dll - (64位/MBCS/DeBug) (7) Bin/x64/HPSocket_U.dll - (64位/UNICODE/Release) (8) Bin/x64/HPSocket_UD.dll - (64位/UNICODE/DeBug) > 其它更新: ----------------- 1、把组件接口以及监听器接口的声明移到 SocketInterface.h 2、IServer 增加接口方法 GetConnectionCount()/GetConnectPeriod() 分别获取当前连接数和某个连接的时长 3、IServer 接口方法 GetListenAddress()/GetClientAddress() 的 CString& 参数改为 LPTSTR 4、IClient 接口方法 GetLocalAddress() 的 CString& 参数改为 LPTSTR 5、SocketHelper.h 所有全局函数的 CString& 参数均改为 LPTSTR 6、示例工程 TestEcho-Pull 和 TestEcho-PFM 改为用动态链接方式使用 HP-Socket > 升级说明: ----------------- 1、使用 HP-Socket v3.0.1 的应用程序可以安全升级到 HP-Socket v3.0.2 2、由于某些接口方法的参数作了调整,因此请参考测试工程作相应修改 3、如果工程想通过动态链接方式使用 HP-Socket,请参考 TestEcho-Pull 或 TestEcho-PFM 示例工程

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值