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
* @郵箱
*/
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