【C++】创建TCP服务端

实现了一个基本的 TCP 服务器,可以接受多个客户端连接,然后持续接收客户端发送的信息, 最后将接收到的信息再发送回客户端 。

源码 

头文件(TCPServerTest.h)

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>

#include <thread>
#include <functional> // 添加这个头文件以使用 std::bind

#include <string>

#pragma comment(lib, "ws2_32.lib")

class TCPSever {
public:
	TCPSever(int port);
	~TCPSever();
	int createSocket();  //创建套接字
	int serverPreparation();  //服务器连接准备
	int startConnectClient();  //接受连接客户端
	void handleClient(SOCKET clientSocket);  //处理客户端

	int Port;
	WSADATA wsaData;
	SOCKET serverSocket;
	struct sockaddr_in serverAddr, clientAddr;
	int addrLen = sizeof(clientAddr);
};

 源文件(TCPServerTest.cpp)

#include "TCPServerTest.h"

TCPSever::TCPSever(int port):Port(port)
{
	// 初始化 Windows Sockets,传入的参数MAKEWORD(2, 2)指定使用 Winsock 2.2 版本,  成功返回0,失败返回非0的错误值
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {  //
		std::cerr << "Error initializing Winsock\n";
	}
	else
	{
		createSocket();
		serverPreparation();
		startConnectClient();
	}
}

TCPSever::~TCPSever()
{
	closesocket(this->serverSocket);  // 关闭与服务端的连接,关闭服务端套接字
	WSACleanup();  //清理 Winsock 库资源
}

int TCPSever::createSocket()
{
	// 创建套接字
	this->serverSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (this->serverSocket == INVALID_SOCKET) {
		std::cerr << "Error creating socket\n";
		WSACleanup();
		return 1;
	}
}

int TCPSever::serverPreparation()
{
	// 设置服务器地址信息
	this->serverAddr.sin_family = AF_INET;
	this->serverAddr.sin_addr.s_addr = INADDR_ANY;
	this->serverAddr.sin_port = htons(Port);

	// bind 函数 可以绑定套接字到指定地址和端口
	if (bind(this->serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
		std::cerr << "Error binding socket\n";
		closesocket(this->serverSocket);
		WSACleanup();
		return 1;
	}

	// listen函数:开始监听连接,参数10表示等待连接队列的最大长度为 10
	if (listen(this->serverSocket, 10) == SOCKET_ERROR) {
		std::cerr << "Error listening for connections\n";
		closesocket(this->serverSocket);
		WSACleanup();
		return 1;
	}
	std::cout << "Server listening on port " << Port << std::endl;
}

int TCPSever::startConnectClient()
{
	while (true)  //循环接收数据
	{
		SOCKET newClientSocket;
		// 接受客户端连接  accept函数:在循环中等待客户端连接,一旦有客户端连接,会返回一个新的套接字用于与该客户端通信,并获取客户端的地址信息
		newClientSocket = accept(this->serverSocket, (struct sockaddr*)&clientAddr, &addrLen);
		if (newClientSocket == INVALID_SOCKET) {
			std::cerr << "Error accepting connection\n";
			continue;
		}
		char clientIP[INET_ADDRSTRLEN];
		if (inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN) == nullptr) {
			std::cerr << "Error converting client IP address\n";
		}
		else {
			std::cout << "Client: " << std::string(clientIP)+ ":" + std::to_string(ntohs(clientAddr.sin_port)) << std::endl;
			std::thread clientThread(std::bind(&TCPSever::handleClient, this, newClientSocket));  //连上后和客户端进行数据
			clientThread.detach();
		}
	}
}

void TCPSever::handleClient(SOCKET clientSocket)
{
	const char* welcomeMessage = "Welcome to the server!\n";
	send(clientSocket, welcomeMessage, strlen(welcomeMessage), 0);  // 向客户端发送信息

	char buffer[1024];
	while (true)
	{
		int bytesRead = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytesRead > 0) {
			buffer[bytesRead] = '\0';
			std::cout << "Received: " << buffer << std::endl;
			std::string response = "received: " + std::string(buffer);
			send(clientSocket, response.c_str(), response.length(), 0);
		}
		else {
			std::cerr << "Connection closed by client\n";
			closesocket(clientSocket);
			return;
		}
	}
}

调用:

#include "TCPServerTest.h"

int main() {
	TCPSever server = TCPSever(8888);
}

结果

可以看到服务端可以支持多个客户端连接 

客户端代码见:

【C++】创建TCP客户端-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Idea序列图插件-SequenceDiagram Core

&#x1f496;简介 SequenceDiagram Core 是一个 IntelliJ IDEA 插件&#xff0c;它允许开发者直接在 IDE中创建和编辑序列图&#xff08;Sequence Diagrams&#xff09;。序列图是 UML&#xff08;统一建模语言&#xff09;中的一种图表类型&#xff0c;用于描述对象之间如何…

【Java 22 | 10】 深入解析Java 22 :Vector API 增强特性

Java 22 对 Vector API 进行了重要增强&#xff0c;旨在提供更高效的矢量操作能力&#xff0c;以支持性能关键的应用程序。Vector API 允许开发者利用硬件的 SIMD&#xff08;单指令多数据&#xff09;特性&#xff0c;从而在处理数组和集合等数据时显著提高性能。 1. 基础介绍…

谷歌-BERT-第一步:模型下载

1 需求 需求1&#xff1a;基于transformers库实现自动从Hugging Face下载模型 需求2&#xff1a;基于huggingface-hub库实现自动从Hugging Face下载模型 需求3&#xff1a;手动从Hugging Face下载模型 2 接口 3.1 需求1 示例一&#xff1a;下载到默认目录 from transform…

微带传输线 - 本征模 - Alpha 衰减常数与S21插损_CST软件案例

关于Beta之前的文章解释了很多&#xff0c;这期说说Alpha。α 是衰减常数&#xff08;attenuation constant&#xff09;&#xff0c;表示波损耗&#xff0c;和S21插损相关&#xff0c;但这几个量很多人还是搞不清楚。 首先&#xff0c;S21和插损Insertion Loss严格上讲是不一…

Spring Boot与JavaWeb协同:在线考试系统的实现“

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于JavaWeb技术的在线考试系统设计与实现…

请求参数中字符串的+变成了空格

前端请求 后端接收到的结果 在URL中&#xff0c;某些字符&#xff08;包括空格、、&、? 等&#xff09;需要被编码。具体而言&#xff0c;在URL中&#xff0c;空格通常被编码为 或 %20。因此&#xff0c;如果你在请求参数中使用 &#xff0c;它会被解释为一个空格。 如果…

【C++贪心】2086. 喂食仓鼠的最小食物桶数|1622

本文涉及知识点 C贪心 LeetCode2086. 喂食仓鼠的最小食物桶数 给你一个下标从 0 开始的字符串 hamsters &#xff0c;其中 hamsters[i] 要么是&#xff1a; ‘H’ 表示有一个仓鼠在下标 i &#xff0c;或者’.’ 表示下标 i 是空的。 你将要在空的位置上添加一定数量的食物桶…

QUIC(Quick UDP Internet Connections)与 RTMP(Real Time Messaging Protocol)

QUIC&#xff08;Quick UDP Internet Connections&#xff09;和 RTMP&#xff08;Real Time Messaging Protocol&#xff09;是两种不同的网络传输协议&#xff0c;它们在一些方面有不同的特点和应用场景。 QUIC 协议 特点 基于 UDP&#xff1a;QUIC 建立在 UDP 之上&#xff…

unity静态批处理

unity静态批处理 静态批处理要求和兼容性渲染管线兼容性 使用静态批处理在构建时进行静态批处理在构建时执行静态批处理的步骤&#xff1a; 在运行时进行静态批处理性能影响 静态批处理 静态批处理是一种绘制调用批处理方法&#xff0c;它将不移动的网格组合在一起&#xff0c…

合并与变形

目录 合并 准备数据 append关键字 concat关键字 merge关键字 join关键字 变形 df.T行列转置 透视表 合并 很多情况下需要将多个df合并为一个新的df df1.append(df2) 纵向合并数据集 pd.concat([df1, df2, ...]) 横向或纵向合并数据集&#xff0c;df1和df2可以没有任何…

企业微信开放平台注册流程

目录 网址 注册步骤 准备工作 填写信息 微信认证 填写发票 支付费用 完成注册 网址 微信开放平台&#xff1a; https://open.weixin.qq.com/ 注册步骤 准备工作 企业版&#xff1a; 没有注册过微信其他平台&#xff08;如&#xff1a;微信小程序&#xff0c;微信公众…

澳鹏干货 | 大语言模型的上下文窗口 (Context Windows)

大语言模型&#xff08;LLMs&#xff09;极大地提升了人工智能在理解和生成文本方面的能力。其中一个影响其效用的重要方面是“上下文窗口”&#xff08;Context Windows&#xff09;—— 这个概念直接影响着模型接收和生成语言的有效性。 本期澳鹏干货将深入探讨上下文窗口对…

【MySQL】增删改查-进阶(一)

目录 &#x1f334;数据库约束 &#x1f6a9;约束类型 &#x1f6a9;NOT NULL &#x1f6a9;UNIQUE &#x1f6a9;DEFAULT &#x1f6a9;PRIMARY KEY &#x1f6a9;FOREIGN KEY &#x1f6a9;CHECK &#x1f384;表的设计 &#x1f6a9;一对一 &#x1f6a9;一对多 …

JavaWeb合集07-MyBatis

七、MyBatis MyBatis是一款优秀的持久层&#xff08;dao&#xff09;框架&#xff0c;用于简化JDBC的开发。 MyBatis本是Apache的一个开源项目iBatis, 2010年这个项目由apache迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。 官网&#xff1a;https://mybati…

人工智能学习框架的探索与应用

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Spark:DataFrame介绍及使用

1. DataFrame详解 DataFrame是基于RDD进行封装的结构化数据类型&#xff0c;增加了schema元数据&#xff0c;最终DataFrame类型在计算时&#xff0c;还是转为rdd计算。DataFrame的结构化数据有Row&#xff08;行数据&#xff09;和schema元数据构成。 Row 类型 表示一行数据 …

中文情感分析课程设计

中文情感分析 中文情感分析的实质是文本分类问题&#xff0c;本项目分别采用CNN和BI-LSTM两种模型解决文本分类任务&#xff0c;并用于情感分析&#xff0c;达到不错的效果。 两种模型在小数据集上训练&#xff0c;在验证集的准确率、号回率及F1因子均接近90% 项目设计的目标…

短链接能有多短?颠覆你的认知

在我们平时的网络活动中&#xff0c;经常会遇到需要将长链接缩短的情况。有细心的小伙伴会发现&#xff0c;平时收到的短信里面都会携带一个很短的链接&#xff0c;这就是将长链接缩短之后的效果。 缩短链接的主要目的有两个&#xff1a;一是使链接更加简洁美观&#xff1b;二…

基于SSM的网上拍卖平台

文未可获取一份本项目的java源码和数据库参考。 1. 选题背景 网络在人们的日常生活所占的比重越来越重&#xff0c;人们对网络信息的依赖性也越来越高。为用户提供良好的网络服务&#xff0c;可以给用户带来便捷的同时&#xff0c;也为网络服务开发商带来了客观的收益。当前&…

4-20mA采集卡 USB温度采集卡 USB热电偶采集 USB5601多功能采集卡

阿尔泰科技 型号&#xff1a;USB5601 概述&#xff1a; 产品外形图&#xff1a; 外形尺寸图&#xff1a; 主要指标&#xff1a; 8 路差分模拟量采集、8 路隔离数字量输入和 8 路隔离数字量输出 要了解更多技术和产品知识关注我吧&#xff01;