1. 程式人生 > >C++ TCP多客戶端通訊《客戶端原始碼》

C++ TCP多客戶端通訊《客戶端原始碼》

顯示效果已將在上一篇中介紹,上一篇連線:https://blog.csdn.net/yangfahe1/article/details/84027628

客戶端標頭檔案


class TCPClient
    : public ITCPClient
{

    DOX_REGISTER_MEMBER(TCPClient, ITCPClient)

public:

    /* @介面 預設建構函式
     * @郵箱 [email protected]
     */
    TCPClient();

    /* @介面 預設解構函式
     * @郵箱 [email protected]
     */
    ~TCPClient();
    
    /* @介面 初始化客戶端
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    virtual bool initClient();
    
    /* @介面 查詢所有的客戶端
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱

[email protected]
     */
    virtual QStringList allClients();

    /* @介面 新增客戶端
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    virtual bool addClient(const QString &);

    /* @介面 查詢客戶端
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 5758[email protected]
     */
    virtual bool findClient(const QString &);
    
    /* @介面 建立客戶端
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    virtual long createClient(int, const QString &ip = "127.0.0.1");
    
    /* @介面 連線伺服器
     * @引數 
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    virtual bool beginConnect(ClientType, PClientCallBack callBack = NULL);

public:
    
    /* @介面 接受資訊
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    QString recv();
    
    /* @介面 傳送資訊
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    bool send(const QString &);
    
    /* @介面 輸出資訊(用作執行緒)
     * @引數 
     * @郵箱 [email protected]
     */
    static DWORD exportRecvInfo(LPVOID);

    /* @介面 接受資訊(用作執行緒)
     * @引數 
     * @郵箱 [email protected]
     */
    static DWORD importSendInfo(LPVOID);

private:

    /* @介面 
     * @返回 bool 成功返回值為true,否則返回值為false
     * @郵箱 [email protected]
     */
    bool beginClientWithServer();

public:

    SOCKET _socket;
    PClientCallBack m_callback;
    HANDLE exportMutex, importMutex;

};
客戶端原始檔


TCPClient::TCPClient()
    , _socket(0)
{

}

TCPClient::~TCPClient()
{
    closesocket(_socket);
    WSACleanup();
}

QString TCPClient::recv()
{
    int size = 1024;
    char *info = new char[size];
    int ret = ::recv(_socket, info, size, 0);
    if(ret == -1) return "Exit";
    QString recvinfo(QS(info));
    delete info; return recvinfo;
}

bool TCPClient::initClient()
{
    WSADATA wsa;
    int ret = WSAStartup(MAKEWORD(2, 3), &wsa);
    ret = WSAGetLastError();
    return ret != 0;
}

QStringList TCPClient::allClients()
{
    Object<IDoxString> doxStr(NIL);
    QString info = doxStr->deciphering("find");
    bool flag = send(info);
    info = doxStr->encryption(recv());
    return recv().split(";");
}

bool TCPClient::beginClientWithServer()
{
    return true;
}

bool TCPClient::send(const QString &info)
{
    char sendinfo[1024] = {0};
    sprintf(sendinfo, "%s", info.toLocal8Bit().constData());
    ::send(_socket, sendinfo, info.length() + 1, NULL);
    return true;
}

DWORD TCPClient::exportRecvInfo(LPVOID param)
{
    if(!param) return -1;
    TCPClient *client = (TCPClient *)param;
    while(true)
    {
        WaitForSingleObject(client->exportMutex, INFINITE);
        if(client->m_callback && client->m_callback->_recv)
        {
            QString info = client->recv();
            if(info == "Exit") exit(0);
            Object<IDoxPointer> ptr(NIL); 
            ptr->setString(info);
            client->m_callback->_recv(ptr);
        }
        ReleaseMutex(client->exportMutex);
    }
    return 0;
}

DWORD TCPClient::importSendInfo(LPVOID param)
{
    TCPClient *client = (TCPClient *)param;
    while(true)
    {
        WaitForSingleObject(client->importMutex, INFINITE);
        if(client->m_callback && client->m_callback->_send)
        {
            Object<IDoxPointer> ptr = client->m_callback->_send();
            client->send(ptr->getString());
        }
        ReleaseMutex(client->importMutex);
    }
    return 0;
}

bool TCPClient::addClient(const QString &client)
{
    return true;
}

bool TCPClient::findClient(const QString &client)
{
    QString info(QS("find:%1").arg(client));
    bool flag = send(info);
    if(flag == false) return false;
    QStringList clients = recv().split(";");
    return true;
}

long TCPClient::createClient(int port, const QString &ip)
{
    _socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in clientAddr;
    memset(&clientAddr, 0, sizeof(SOCKADDR));
    clientAddr.sin_addr.s_addr = inet_addr(ip.toLocal8Bit().constData());
    clientAddr.sin_family = AF_INET;
    clientAddr.sin_port = htons(port);
    int ret = connect(_socket, (SOCKADDR*)&clientAddr, sizeof(SOCKADDR));
    QString info = recv(); return info.toLong();
}

bool TCPClient::beginConnect(ClientType type, PClientCallBack callBack)
{
    if(callBack == NULL) return false;
    m_callback = callBack;
    HANDLE _handle[2];
    switch(type)
    {
        case ClientWithClient:
            exportMutex = CreateMutex(NULL, FALSE, NULL);
            importMutex = CreateMutex(NULL, FALSE, NULL);
            _handle[0] = CreateThread(NULL, 0, exportRecvInfo, this, 0, NULL);
            _handle[1] = CreateThread(NULL, 0, importSendInfo, this, 0, NULL);
            WaitForMultipleObjects(2, _handle, TRUE, INFINITE); return true;
        case ClientWithServer: return beginClientWithServer();
    }
    return false;
}


客戶端原始檔結束

示例程式下載地址:https://download.csdn.net/download/yangfahe1/10781733

示例程式執行方式:https://blog.csdn.net/yangfahe1/article/details/84028318