显示效果已将在上一篇中介绍,上一篇连接:https://blog.csdn.net/yangfahe1/article/details/84027628
客户端头文件
class TCPClient
: public ITCPClient
{
DOX_REGISTER_MEMBER(TCPClient, ITCPClient)
public:
/* @接口 默认构造函数
* @邮箱 575814050@qq.com
*/
TCPClient();
/* @接口 默认析构函数
* @邮箱 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 &);
/* @接口 查找客户端
* @返回 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);
/* @接口 接受信息(用作线程)
* @参数
* @邮箱 575814050@qq.com
*/
static DWORD importSendInfo(LPVOID);
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