C++封装TCP类,包括客户端和服务器

news2025/2/23 1:33:42

头文件 XTcp.h

#ifndef XTCP_H
#define XTCP_H

#ifdef WIN32
#ifdef XSOCKET_EXPORTS
#define XSOCKET_API __declspec(dllexport)
#else
#define XSOCKET_API __declspec(dllimport)
#endif
#else
#define XSOCKET_API
#endif

#include <string>
XSOCKET_API std::string GetIpByHost(std::string host);

//class XSOCKET_API XTcp
class XTcp
{
public:
	int CreateSocket();
	bool Bind(unsigned short port);
	XTcp Accept();
	void Close();
	int Recv(char *buf,int bufsize);
	int Send(const char *buf,int sendsize);
	bool Connect(const char *ip,unsigned short port,int timeoutms=1000);
	bool SetBlock(bool isblock);
	XTcp();
	virtual ~XTcp();
	int sock;
	unsigned short port;
	char ip[16];

};

#endif

源文件 XTcp.cpp

#include "XTcp.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define WIN32

#ifdef WIN32
#pragma comment(lib, "ws2_32.lib")
#include <windows.h>
#define socklen_t int
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#define  closesocket close
#endif

//#include <thread>
using namespace std;
XSOCKET_API std::string GetIpByHost(std::string host)
{
	hostent *hptr = gethostbyname(host.c_str());
	if (!hptr)return "";
	in_addr addr;
	addr.s_addr = *(unsigned long *)hptr->h_addr;
	return inet_ntoa(addr);
}
XTcp::XTcp()
{
	sock = 0;
	port = 0;
#ifdef WIN32
	static bool first = true;
	if (first)
	{
		first = false;
		WSADATA ws;
		WSAStartup(MAKEWORD(2, 2), &ws);
	}
#endif
}
int XTcp::CreateSocket()
{
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1)
	{
		printf("create socket failed!\n");
	}
	return sock;
}
bool XTcp::Bind(unsigned short port)
{
	if (sock <= 0)
		CreateSocket();
	sockaddr_in  saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr.s_addr = htonl(0);
	if (::bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0)
	{
		printf("bind port %d failed!\n", port);
		return false;
	}
	printf("bind port %d success!\n", port);
	listen(sock, 1000);
	return true;
}
int XTcp::Recv(char *buf, int bufsize)
{
	return recv(sock, buf, bufsize, 0);
}
int XTcp::Send(const char *buf, int size)
{
	int s = 0;
	while (s != size)
	{
		int len = send(sock, buf + s, size - s, 0);
		if (len <= 0)break;
		s += len;
	}
	return s;
}
void XTcp::Close()
{
	if (sock <= 0) return;
	closesocket(sock);
	sock = 0;
}
XTcp XTcp::Accept()
{
	XTcp tcp;
	sockaddr_in caddr;
	socklen_t len = sizeof(caddr);
	int client = accept(sock, (sockaddr*)&caddr, &len);
	if (client <= 0) return tcp;
	//printf("accept client %d\n", client);
	printf(".");
	char *ip = inet_ntoa(caddr.sin_addr);
	strcpy(tcp.ip, ip);
	tcp.port = ntohs(caddr.sin_port);
	tcp.sock = client;
	//printf("client ip is %s,port is %d\n", tcp.ip, tcp.port);
	return tcp;
}

bool XTcp::Connect(const char *ip,unsigned short port,int timeoutms)
{
	if(sock <=0 ) CreateSocket();
	sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr.s_addr = inet_addr(ip);
	SetBlock(false);
	fd_set set;
	if(connect(sock,(sockaddr*)&saddr,sizeof(saddr))!=0)
	{
		FD_ZERO(&set);
		FD_SET(sock,&set);
		timeval tm;
		tm.tv_sec = 0;
		tm.tv_usec = timeoutms*1000;
		if(select(sock+1,0,&set,0,&tm) <= 0)
		{
			printf("connect timeout or error!\n");
			printf("connect %s:%d failed!:%s\n",ip,port,strerror(errno));
			return false;
		}
	}
	SetBlock(true);
	printf("connect %s:%d success!\n",ip,port);
	return true;
}
XTcp::~XTcp()
{
}
bool XTcp::SetBlock(bool isblock)
{
	if(sock<=0) return false;
	#ifdef WIN32
		unsigned long ul = 0;
		if(!isblock) ul = 1;
		ioctlsocket(sock,FIONBIO,&ul);
	#else
		int flags = fcntl(sock,F_GETFL,0);
		if(flags<0)
			return false;
		if(isblock)
		{
			flags = flags&~O_NONBLOCK;
		}
		else
		{
			flags = flags|O_NONBLOCK;
		}
		if(fcntl(sock,F_SETFL,flags)!=0)
			return false;
	#endif
	return true;
}

服务器 server.cpp

#include <stdlib.h>
#include <windows.h>
#include "XTcp.h"
#include <string.h>
#include <iostream>


XTcp client;

DWORD WINAPI ThreadFunction(LPVOID lpParam) {
    // 线程要执行的代码
    char buf[1024] = {0};
	for (;;)
	{
		int recvlen = client.Recv(buf,sizeof(buf)-1);
		if (recvlen <= 0) break;
		buf[recvlen] = '\0';
				
		if (strstr(buf, "quit") != NULL)
		{
			char re[] = "quit success!\n";
			client.Send(re,strlen(re)+1);
			break;
		}
		int sendlen = client.Send("ok\n", 4);
		printf("recv %s\n",buf);
	}
	client.Close();
    return 0;
}

int main(int argc,char *argv[])
{
	unsigned short port = 8080;
	if (argc > 1)
	{
		port = atoi(argv[1]);
	}
	XTcp server;
	server.CreateSocket();
	server.Bind(port);
	for(;;)
	{
		client = server.Accept();
		// 创建线程
		HANDLE hThread;
		DWORD dwThreadId;
		hThread = CreateThread(
			NULL, // 安全属性
			0,    // 初始堆栈大小
			ThreadFunction, // 线程函数
			NULL, // 线程函数的参数
			0,    // 创建标志
			&dwThreadId); // 线程ID的指针
	}
	server.Close();
	getchar();
	return 0;
}

客户端 client.cpp

#include "XTcp.h"
#include <iostream>
#include <Windows.h>

int main()
{
	for(;;)
	{
		XTcp client;
		client.CreateSocket();
		client.SetBlock(false);
		client.Connect("127.0.0.1",8080,3000);

		char msg[1024] = "hhhh";
		int len = strlen(msg);
		client.Send(msg, strlen(msg));

		char buf[1024] = { 0 };
		client.Recv(buf, sizeof(buf));
		printf("%s\n", buf);

		client.Close();

		Sleep(10);
	}

	getchar();
}

运行结果

服务器

在这里插入图片描述

客户端

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839085.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宁德时代华北首座电池工厂在北京开工

6月18日&#xff0c;由宁德时代与北汽集团、京能集团、小米集团等共同投资建设的北京时代电池基地项目开工仪式在北京举行。 北京市相关政府代表&#xff0c;宁德时代董事长兼CEO曾毓群&#xff0c;北汽集团董事长张建勇&#xff0c;京能集团副总经理张凤阳&#xff0c;小米集…

第6章 设备驱动程序(4)

目录 6.5 块设备操作 6.5.5 请求结构 6.5.6 BIO 6.5.7 提交请求 6.5.8 I/O调度 6.5.9 ioctl实现 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 6.5 块设备操作 6.5.5 请求结构 struct request { //放在请求队列上&#xff0…

BFS 1块、算多少次

目录 1.矩阵内部的1块 2.从1开始&#xff0c;1或乘2&#xff0c;计算要多少次达到n 3.迷宫路径 1.矩阵内部的1块 #include <iostream> #include <vector> #include <cmath> #include <string> #include <cstring> #include <queue> usi…

现代谱估计分析信号的功率谱(1)---AR 模型谱估计

本篇文章是博主在通信等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对通信等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在通信领域笔记&#xff1a;…

1951–2021年欧洲地区木本植物的格网物候数据集

本数据集包含1951–2021年欧洲地区&#xff08;3457′N – 723′N&#xff0c;253′W – 403′E&#xff09;6种木本植物的逐年展叶始期和开花始期格网数据&#xff0c;空间分辨率为0.1&#xff0c;时间分辨率为1天。数据集的质量评估表明&#xff0c;欧洲地区各物种展叶始期和…

车载语音识别系统语音数据采集标注案例

随着人工智能技术的不断发展&#xff0c;其在我们日常生活工作场景中的应用也越来越普及&#xff0c;人工智能技术在不同场景的普及大大的提高了我们日常生活、工作的高效性和便利性。以我们的日常出行为例&#xff0c;车载语音识别系统便是一种典型的人工智能应用场景。 车载…

大咖专栏 | AI 时代下,我们可以拥有怎样的数据库?

Hi&#xff0c;各位朋友们&#xff0c;我是 KaiwuDB 高级架构师赵衎衎。 KaiwuDB 始于万物互联时代下千万条数据洪流中&#xff0c;我们持续打磨构造了更加灵活兼容的分布式多模架构&#xff0c;实现了海量异构数据高性能、低成本的集中管理… …这些底层特性都在为后续提供更…

初见DP

线性DP 例题1 1143. 最长公共子序列 &#xff08;LCS&#xff09; 子序列不连续 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#x…

单片机第五季-第八课:STM32CubeMx和FreeRTOS

1&#xff0c;FreeRTOS背景介绍 RTOS简介&#xff1a; 实时操作系统&#xff0c;本用于追求实时性的嵌入式系统&#xff0c;典型&#xff1a;ucos/uclinux/vxworks&#xff1b; 特点&#xff1a;中断响应快、一般可嵌套中断、使用实地址、多任务&#xff1b; &#xff08;实…

如何用Vue3构建一个交互式树状图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue 3 ApexCharts Treemap 组件&#xff1a;可视化多维数据 应用场景 树形图&#xff08;Treemap&#xff09;是一种可视化多维数据的有效方式&#xff0c;特别适用于展示层次结构数据或按类别分组的数据。它…

Flink 资源静态调度

本内容是根据 Flink 1.18.0-Scala_2.12 版本源码梳理而来。本文主要讲述任务提交时&#xff0c;为 Task 分配资源的过程。 以下是具体步骤讲解&#xff1a; TaskManager 资源注册 TaskManager 再启动时&#xff0c;会向 ResourceManager 注册资源。ResourceManager 会将 Tas…

Debian12安装Nvidia官方驱动

1、下载驱动&#xff08;下载到一个英文目录例如你的用户目录/home/用户名下&#xff0c;我下载到dowload目录&#xff0c;由于默认显示中文&#xff0c;在命令行不支持中文显示的是一串数字&#xff0c;当然你仍然可以cd 那串数字进目录&#xff0c;显示有有引号就加引号&…

香港优才计划申请打分、材料、递交攻略,2024年获批后我来分享

香港优才计划这两年很多人弄啊&#xff0c;糖爸作为获批过来人&#xff0c;我来给大家分享香港优才计划申请攻略。 一、香港优才计划如何计算分数&#xff1f; 香港优才计划申请条件分2部分&#xff1a;第一是基本资格要求&#xff0c;第二是计分制度&#xff1b; 基本条件简…

前端框架中的路由(Routing)和前端导航(Front-End Navigation)

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端框架中的路由&#xff08;Routing&#xff09;和前端导航&#xff08;Front-End Navigation&#xff09;1. 路由&#xff08;Routing&#xff09;1.1 定义1.2 路由的核心概念1.2.1 路由表&#xff08;Route Table&#xff09;1…

Pentest Muse:一款专为网络安全人员设计的AI助手

关于Pentest Muse Pentest Muse是一款专为网络安全研究人员和渗透测试人员设计和开发的人工智能AI助手&#xff0c;该工具可以帮助渗透测试人员进行头脑风暴、编写Payload、分析代码或执行网络侦查任务。除此之外&#xff0c;Pentest Muse甚至还能够执行命令行代码并以迭代方式…

【信息资源组织与管理】【开卷考】如何准备 期末考试复习必备

索引篇 先去xhs找了开卷考有什么准备技巧&#xff0c;来自Prozac ❗️首先&#xff0c;适用于考试范围为课本内容或者课堂内容&#xff0c;如果有那种拓展题&#xff0c;脱离课本的&#xff0c;那我就没办法了。 ✅一定要熟悉熟悉熟悉课本 1. 第一遍略看课本&#xff0c;可以不…

navcat 随机生成数据

我最近才知道navcat能随机生成数据&#xff0c;所以分享下 下一步&#xff0c;下一步就可以了&#xff0c;我们就成功了

芯片验证分享9 —— 芯片调试

大家好&#xff0c;我是谷公子&#xff0c;之前的课程给大家讲了验证原则、激励设计和代码审查&#xff0c;今天我们来讲芯片调试。 芯片调试是执行一次成功的验证之后要进行的工作。记住&#xff0c;所谓成功的验证&#xff0c;是指它可以证明芯片没有实现预期的功能。调试主…

不是所有洗碗机都能空气除菌 友嘉灵晶空气除菌洗碗机评测

精致的三餐让你以为生活是“享受”&#xff0c;可饭后那些油腻的锅碗瓢盆却成了你我美好生活的最大障碍。想要只吃美食不洗碗&#xff0c;那一台优秀的洗碗机就必不可少了&#xff01;今天&#xff0c;ZOL中关村在线要评测的就是这样一台不光洗得干净更能有效除菌抑菌的洗碗机—…

UE4_材质_湿度着色器及Desaturation算法_ben材质教程

学习笔记&#xff0c;不喜勿喷&#xff01;侵权立删&#xff0c;祝愿美好生活越来越好。 效果图&#xff1a; 原图&#xff1a; 1、使用初学者内容包的材质 我们这里使用虚幻自带的材质M_Brick_Clay_Old,复制一个更名为M_Brickclayoldwet材质。 2、添加去饱和度Desaturation节…