栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

封装一个TCP客户端类

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

封装一个TCP客户端类

TCPClient

写一个Windows环境下的TCP客户端,功能比较简单。
创建一个对象,即可连上服务器;并应用了一个有限状态机,在与服务器断开连接时,会自动尝试与服务器建立连接;在接收发送数据上,仅做测试通讯是否正常,被动接收数据,然后再把数据发送回给服务器;其中用到的my_thread.h,在另一篇文章有介绍


TcpClient.h
#pragma once
#include 
#include 
#include "my_thread.h"
using namespace std;

class TcpClient
{
private:
	SOCKET					sclient_ = INVALID_SOCKET;	
	const char*				ip_ = NULL;					
	u_short					port_ = 0;
private:
	my_thread				my_thread_;  
	my_thread::Thread   	thread_id_;			
	int						link_step_;			
	my_thread::Mutex    	link_step_mutex_;	
	my_thread::Mutex    	send_mutex_;		

private:

	
	void ThreadWhile(void* arg);
	
	bool linkServer();
	
	int Initialize();
	
	bool Start();
public:
	
	bool ConnectStatus();
	
	int Send(const char* buffer, int len);
	
	TcpClient(const char* ip, u_short port);
	
	~TcpClient();
};



TcpClient.h
#include "TCPClient.h"
#include 
#include 
#include 
#pragma comment(lib,"ws2_32.lib")
using namespace std;




int TcpClient::Initialize() {

	WORD version = MAKEWORD(2, 2);
	WSADATA data;
	
	if (WSAStartup(version, &data) != 0) {
		std::cout << "WSAStartup Failed!"<Initialize();

	my_thread_.createThread(thread_id_, &TcpClient::ThreadWhile,this,NULL);
	return true;
}



bool TcpClient::linkServer()
{
	bool ret = false;
	if (sclient_>0) {
		closesocket(sclient_);
	}
	sclient_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(port_);
	servAddr.sin_addr.S_un.S_addr = inet_addr(ip_);

	if (connect(sclient_, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR )
	{
		std::cout << "Connect Failed!" << std::endl;
		ret = false;
	}
	else {
		std::cout << "Connect Success!" << std::endl;
		ret = true;
	}
	return ret;
}




int TcpClient::Send(const char* buffer, int len) {
	if (!ConnectStatus()) {
		return -1;
	}
	my_thread_.lock(send_mutex_);
	int flag = send(sclient_,buffer,len,0);
	my_thread_.unlock(send_mutex_);
	if (flag== len) {
		std::cout << "Send Success!" << std::endl;
		return 1;
	}
	std::cout << "Send Failed!" << std::endl;
	return 0;
}


bool TcpClient::ConnectStatus() {
	bool ret = false;
	my_thread_.lock(link_step_mutex_);
	if (link_step_>0) {
		ret=  true;
	}
	my_thread_.unlock(link_step_mutex_);
	return ret;
}




void TcpClient::ThreadWhile(void* arg)
{
	unsigned char buffer[4096] = { 0 };
	int ret = 0;

	while (1) {
		switch (link_step_) {
		case 0:
			if (linkServer()) {
				link_step_++;
				break;
			}
			break;
		case 1:
			ret = recv(sclient_, (char*)buffer, sizeof(buffer), 0);
			// -1 接收失败  0 断开连接 
			if (ret <= 0) {
				link_step_ = 0;
				break;
			}
			else {
				Send((char*)buffer,ret);
			}
			break;
		default:
			break;
		}
	}
}


TcpClient::TcpClient(const char* ip, u_short port) {
	
	ip_ = ip;
	port_ = port;

	thread_id_ = NULL;
	link_step_mutex_ = NULL;
	send_mutex_ = NULL;
	my_thread_.createMutex(link_step_mutex_);
	my_thread_.createMutex(send_mutex_);
	link_step_ = 0;
	sclient_ = INVALID_SOCKET;
	Start();
}


TcpClient::~TcpClient() {
	if (sclient_ != INVALID_SOCKET) {
		closesocket(sclient_);
	}
	my_thread_.deleteMutex(link_step_mutex_);
	my_thread_.deleteMutex(send_mutex_);
	WSACleanup();
	sclient_ = INVALID_SOCKET;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/748234.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号