您的位置:首页 > 汽车 > 时评 > 金华网站制作营销_企业网站建设免费_阿里巴巴seo排名优化_百度搜索指数排行

金华网站制作营销_企业网站建设免费_阿里巴巴seo排名优化_百度搜索指数排行

2024/12/22 19:38:48 来源:https://blog.csdn.net/doubleintfloat/article/details/144392138  浏览:    关键词:金华网站制作营销_企业网站建设免费_阿里巴巴seo排名优化_百度搜索指数排行
金华网站制作营销_企业网站建设免费_阿里巴巴seo排名优化_百度搜索指数排行

TcpClient.h

#ifndef TCPCLIENT_H
#define TCPCLIENT_H#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <vector>// 引入静态链接库
#pragma comment(lib, "ws2_32.lib")class TcpClient {
public:TcpClient();~TcpClient();// 连接到指定服务器bool connectToServer(const char* serverIp, int port);// 发送数据,非阻塞方式int sendData(const char* data, int dataLength);// 接收数据,非阻塞方式int receiveData(char* buffer, int bufferSize);// 启动心跳包机制,参数为心跳间隔时间(单位:秒)void startHeartbeat(int interval);// 停止心跳包机制void stopHeartbeat();private:SOCKET clientSocket;bool isHeartbeatRunning;int heartbeatInterval;HANDLE heartbeatThreadHandle;// 发送心跳包的函数(需要定义为静态函数,以便在线程函数中调用)static DWORD WINAPI SendHeartbeat(LPVOID lpParam);// 辅助函数,用于非阻塞模式下完整发送数据int sendAllData(const char* data, int dataLength);// 辅助函数,用于非阻塞模式下完整接收数据int receiveAllData(char* buffer, int bufferSize);
};#endif

TcpClient.cpp

#include "TcpClient.h"// 构造函数,初始化客户端套接字
TcpClient::TcpClient() : clientSocket(INVALID_SOCKET), isHeartbeatRunning(false), heartbeatInterval(0),
heartbeatThreadHandle(NULL) {WSADATA wsaData;int result = WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0) {std::cerr << "WSAStartup failed: " << result << std::endl;}
}// 析构函数,关闭套接字并清理WinSock环境
TcpClient::~TcpClient() {if (clientSocket != INVALID_SOCKET) {closesocket(clientSocket);}stopHeartbeat();WSACleanup();
}// 连接到指定服务器
bool TcpClient::connectToServer(const char* serverIp, int port) {clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (clientSocket == INVALID_SOCKET) {std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;return false;}// 设置套接字为非阻塞模式u_long iMode = 1;int result = ioctlsocket(clientSocket, FIONBIO, &iMode);if (result == SOCKET_ERROR) {std::cerr << "ioctlsocket failed: " << WSAGetLastError() << std::endl;closesocket(clientSocket);return false;}sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(port);result = inet_pton(AF_INET, serverIp, &serverAddr.sin_addr);if (result <= 0) {std::cerr << "Invalid server IP address" << std::endl;closesocket(clientSocket);return false;}result = ::connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));if (result == SOCKET_ERROR) {if (WSAGetLastError() != WSAEWOULDBLOCK) {std::cerr << "Connect to server failed: " << WSAGetLastError() << std::endl;closesocket(clientSocket);return false;}}// 使用select等待连接完成fd_set writefds;FD_ZERO(&writefds);FD_SET(clientSocket, &writefds);struct timeval timeout;timeout.tv_sec = 5;  // 设置超时时间为5秒,可根据实际调整timeout.tv_usec = 0;result = select(clientSocket + 1, NULL, &writefds, NULL, &timeout);if (result == SOCKET_ERROR) {std::cerr << "Select failed while waiting for connection: " << WSAGetLastError() << std::endl;closesocket(clientSocket);return false;}else if (result == 0) {std::cerr << "Connection timeout" << std::endl;closesocket(clientSocket);return false;}return true;
}// 发送数据,非阻塞方式
int TcpClient::sendData(const char* data, int dataLength) {if (clientSocket == INVALID_SOCKET) {std::cerr << "Client socket is not valid, cannot send data" << std::endl;return SOCKET_ERROR;}return sendAllData(data, dataLength);
}// 接收数据,非阻塞方式
int TcpClient::receiveData(char* buffer, int bufferSize) {if (clientSocket == INVALID_SOCKET) {std::cerr << "Client socket is not valid, cannot receive data" << std::endl;return SOCKET_ERROR;}return receiveAllData(buffer, bufferSize);
}// 启动心跳包机制,参数为心跳间隔时间(单位:秒)
void TcpClient::startHeartbeat(int interval) {if (isHeartbeatRunning) {return;}isHeartbeatRunning = true;heartbeatInterval = interval;// 创建线程,传入当前对象指针作为参数,线程启动函数为 SendHeartbeatheartbeatThreadHandle = CreateThread(NULL, 0, SendHeartbeat, this, 0, NULL);if (heartbeatThreadHandle == NULL) {isHeartbeatRunning = false;std::cerr << "Create heartbeat thread failed: " << GetLastError() << std::endl;}
}// 停止心跳包机制
void TcpClient::stopHeartbeat() {isHeartbeatRunning = false;if (heartbeatThreadHandle != NULL) {// 等待线程结束WaitForSingleObject(heartbeatThreadHandle, INFINITE);CloseHandle(heartbeatThreadHandle);heartbeatThreadHandle = NULL;}
}// 发送心跳包的函数(静态成员函数)
DWORD WINAPI TcpClient::SendHeartbeat(LPVOID lpParam) {TcpClient* client = static_cast<TcpClient*>(lpParam);const char* heartbeatData = "HEARTBEAT";  // 简单的心跳包内容,可自定义int dataLength = strlen(heartbeatData);while (client->isHeartbeatRunning){if (client->clientSocket != INVALID_SOCKET){int sentBytes = client->sendAllData(heartbeatData, dataLength);if (sentBytes == SOCKET_ERROR){// 发送心跳包失败,可以在这里添加相应的处理逻辑,比如尝试重连等std::cerr << "Send heartbeat failed: " << WSAGetLastError() << std::endl;}else{// 尝试接收服务器对心跳包的响应char responseBuffer[10] = {0};int receivedBytes = client->receiveAllData(responseBuffer, sizeof(responseBuffer));if (receivedBytes <= 0) {// 没收到响应或者接收出错,可认为连接可能有问题,添加相应处理逻辑std::cerr << "No response for heartbeat, connection may be broken" << std::endl;}else{std::cout << responseBuffer << std::endl;}}}// 使用 Sleep 函数替代 std::this_thread::sleep_for,单位是毫秒,所以要换算成毫秒Sleep(client->heartbeatInterval * 1000);}return 0;
}// 辅助函数,用于非阻塞模式下完整发送数据
int TcpClient::sendAllData(const char* data, int dataLength) {int totalBytesSent = 0;while (totalBytesSent < dataLength) {int bytesSent = ::send(clientSocket, data + totalBytesSent, dataLength - totalBytesSent, 0);if (bytesSent == SOCKET_ERROR) {if (WSAGetLastError() == WSAEWOULDBLOCK) {// 暂时无法发送,等待下次尝试continue;}return SOCKET_ERROR;}totalBytesSent += bytesSent;}return totalBytesSent;
}// 辅助函数,用于非阻塞模式下完整接收数据
int TcpClient::receiveAllData(char* buffer, int bufferSize) {int totalBytesReceived = 0;while (totalBytesReceived < bufferSize) {int bytesReceived = ::recv(clientSocket, buffer + totalBytesReceived, bufferSize - totalBytesReceived, 0);if (bytesReceived == SOCKET_ERROR){if (WSAGetLastError() == WSAEWOULDBLOCK){// 暂时无数据可读,等待下次尝试continue;}return SOCKET_ERROR;}else if (bytesReceived == 0){// 客户端关闭连接return totalBytesReceived;}totalBytesReceived += bytesReceived;//if (totalBytesReceived > 0)//{//    break;//}}return totalBytesReceived;
}

main.cpp

#include "TcpClient.h"
#include <string>int main() {TcpClient client;if (client.connectToServer("127.0.0.1", 6001)){client.startHeartbeat(1);  // 启动心跳包机制,间隔时间为5秒while (1){/*   std::string message = "Hello, server!";int sentBytes = client.sendData(message.c_str(), message.length());if (sentBytes > 0){char buffer[1024] = {0};int receivedBytes = client.receiveData(buffer, sizeof(buffer));if (receivedBytes > 0){buffer[receivedBytes] = '\0';std::cout << "Received from server: " << buffer << std::endl;}else{std::cout << "Received from server: " << buffer << std::endl;}}*/}client.stopHeartbeat();  // 停止心跳包机制}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com