C++ TCP多客户端通信《客户端源码》

显示效果已将在上一篇中介绍,上一篇链接:http://www.javashuo.com/article/p-mxpnlyct-em.html服务器

客户端头文件


class TCPClient
    : public ITCPClient
{socket

    DOX_REGISTER_MEMBER(TCPClient, ITCPClient)函数

public:this

    /* @接口 默认构造函数
     * @邮箱 575814050@qq.com
     */
    TCPClient();.net

    /* @接口 默认析构函数
     * @邮箱 575814050@qq.com
     */
    ~TCPClient();
    
    /* @接口 初始化客户端
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    virtual bool initClient();
    
    /* @接口 查询全部的客户端
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    virtual QStringList allClients();线程

    /* @接口 添加客户端
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    virtual bool addClient(const QString &);blog

    /* @接口 查找客户端
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    virtual bool findClient(const QString &);
    
    /* @接口 建立客户端
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    virtual long createClient(int, const QString &ip = "127.0.0.1");
    
    /* @接口 链接服务器
     * @参数 
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    virtual bool beginConnect(ClientType, PClientCallBack callBack = NULL);接口

public:
    
    /* @接口 接受信息
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    QString recv();
    
    /* @接口 发送信息
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    bool send(const QString &);
    
    /* @接口 输出信息(用做线程)
     * @参数 
     * @邮箱 575814050@qq.com
     */
    static DWORD exportRecvInfo(LPVOID);ip

    /* @接口 接受信息(用做线程)
     * @参数 
     * @邮箱 575814050@qq.com
     */
    static DWORD importSendInfo(LPVOID);ci

private:

    /* @接口 
     * @返回 bool 成功返回值为true,不然返回值为false
     * @邮箱 575814050@qq.com
     */
    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