当前位置: 首页 > news >正文

socket 收发TCP/UDP

一、c++

个人测试记录,有问题还请指出,谢谢

参考:C++开发基础之网络编程WinSock库使用详解TCP/UDP Socket开发_c++ udp使用什么库-CSDN博客

代码中Logger测试见文章: c++中spdlog的使用/python中logger的使用-CSDN博客

1、main.cpp

收发TCP信号:

#include <iostream>
#include <thread>
#include <vector>#include "Logger.h"
#include "SocketManager.h"#pragma warning(disable:4996)int main() {initLogger();SocketManager socket_manager;// 使用 std::thread 并传递成员函数的指针和对象实例的引用std::thread t1(&SocketManager::get_from_tcp, &socket_manager, 11100);// std::thread t2(&SocketManager::get_from_udp, &socket_manager, 11111);std::thread t3(&SocketManager::send_to_tcp, &socket_manager, "123456", "127.0.0.1", 11100);// std::thread t4(&SocketManager::send_to_udp, &socket_manager, "123456", "127.0.0.1", 11111);t1.detach();// t2.detach();t3.detach();// t4.detach();Sleep(6000000);return 0;
}

 运行结果如下:

 收发UDP信号:

#include <iostream>
#include <thread>
#include <vector>#include "Logger.h"
#include "SocketManager.h"#pragma warning(disable:4996)int main() {initLogger();SocketManager socket_manager;// 使用 std::thread 并传递成员函数的指针和对象实例的引用// std::thread t1(&SocketManager::get_from_tcp, &socket_manager, 11100);std::thread t2(&SocketManager::get_from_udp, &socket_manager, 11111);// std::thread t3(&SocketManager::send_to_tcp, &socket_manager, "123456", "127.0.0.1", 11100);std::thread t4(&SocketManager::send_to_udp, &socket_manager, "123456", "127.0.0.1", 11111);// t1.detach();t2.detach();// t3.detach();t4.detach();Sleep(6000000);return 0;
}

 运行结果如下:

2、SocketManager.h

// #pragma once  // 为确保在不同编译环境中使用,可以使用#define的方法
#ifndef	SOCKETMANAGER_H
#define SOCKETMANAGER_H#include <iostream>
#include <stdio.h>
#include <winsock2.h>
#include <string>
#include "Logger.h"#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)std::string asciiToHex(const std::string& asciiStr); // 将ascii码转为十六进制class SocketManager {
public:SocketManager();~SocketManager();void initialization();  // 初始化套接字库void get_from_udp(int);   // 从客户端接收发来的udp信息void get_from_tcp(int); // 从客户端接收发来的tcp信息void send_to_tcp(std::string, std::string, int);  // 向服务端发送tcp信息void send_to_udp(std::string, std::string, int);  // 向服务端发送udp信息private://定义服务端套接字,接受请求套接字SOCKET ListenSocket_UDP_get;SOCKET ListenSocket_TCP_get;SOCKET SendSocket_UDP_to;SOCKET SendSocket_TCP_to;//服务端/客户端地址SOCKADDR_IN service_UDP_get;SOCKADDR_IN service_TCP_get;SOCKADDR_IN service_UDP_to;SOCKADDR_IN service_TCP_to;
};#endif  // SOCKETMANAGER_H

3、SocketManager.cpp

#include "SocketManager.h"SocketManager::SocketManager() {ListenSocket_UDP_get = INVALID_SOCKET;ListenSocket_TCP_get = INVALID_SOCKET;SendSocket_UDP_to = INVALID_SOCKET;SendSocket_TCP_to = INVALID_SOCKET;
}SocketManager::~SocketManager() {if (ListenSocket_UDP_get != INVALID_SOCKET) {closesocket(ListenSocket_UDP_get);WSACleanup();}if (ListenSocket_TCP_get != INVALID_SOCKET) {closesocket(ListenSocket_TCP_get);WSACleanup();}if (SendSocket_UDP_to != INVALID_SOCKET) {closesocket(SendSocket_UDP_to);WSACleanup();}if (SendSocket_TCP_to != INVALID_SOCKET) {closesocket(SendSocket_TCP_to);WSACleanup();}
}void SocketManager::get_from_udp(int port) {// 初始化套接字库initialization();// 创建套接字ListenSocket_UDP_get = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if (ListenSocket_UDP_get == INVALID_SOCKET) {logger->error("创建套接字失败:" + WSAGetLastError());std::cout << "创建套接字失败:"<< WSAGetLastError() << std::endl;WSACleanup();exit(0);}//填充服务端信息service_UDP_get.sin_family = AF_INET;  // 设置地址族为 IPv4service_UDP_get.sin_addr.s_addr = INADDR_ANY;  // 将 IP 地址设置为 0.0.0.0,表示绑定到所有本地 IP 地址service_UDP_get.sin_port = htons(port);   // 将端口号转换为网络字节序,并设置为指定的端口号// 绑定套接字if (bind(ListenSocket_UDP_get, (SOCKADDR*)&service_UDP_get, sizeof(service_UDP_get)) == SOCKET_ERROR){logger->error("绑定套接字失败: " + WSAGetLastError());std::cout << "绑定套接字失败: " + WSAGetLastError() << std::endl;closesocket(ListenSocket_UDP_get);WSACleanup();exit(0);}char recvbuf[512];  // 定义接收信息的缓冲区,大小为512字节int iRecvResult;  // 存储接收操作的返回结果sockaddr_in clientAddr;   // 用于存储客户端的地址信息int iAddrLen = sizeof(clientAddr);  // 存储地址结构体的大小do{	std::cout << "服务端正在等待数据发送,请稍候...." << std::endl;// 接收来自客户端的数据iRecvResult = recvfrom(ListenSocket_UDP_get, recvbuf, sizeof(recvbuf), 0, (SOCKADDR*)&clientAddr, &iAddrLen);// std::cout << iRecvResult << std::endl;// 检查接收操作是否成功if (iRecvResult > 0){std::string result(recvbuf, iRecvResult);std::cout << "收到信息:" + result << std::endl;logger->info("收到信息:" + result);// 将接收到的数据发送回客户端// sendto(ListenSocket_UDP, recvbuf, iRecvResult, 0, (SOCKADDR*)&clientAddr, sizeof(clientAddr));}else if (iRecvResult == 0){std::cout << "连接关闭" << std::endl;logger->info("连接关闭");}else{std::cout << "接受信息失败:" << WSAGetLastError() << std::endl;logger->error("接受信息失败:" + WSAGetLastError());closesocket(ListenSocket_UDP_get);WSACleanup();}} while (iRecvResult > 0);closesocket(ListenSocket_UDP_get);WSACleanup();
}void SocketManager::initialization() {//初始化套接字库WORD w_req = MAKEWORD(2, 2);//版本号WSADATA wsadata;int err;err = WSAStartup(w_req, &wsadata);if (err != 0) {std::cout << "初始化套接字库失败!" << std::endl;}//检测版本号if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {std::cout << "套接字库版本号不符!" << std::endl;WSACleanup();}//填充服务端地址信息
}void SocketManager::send_to_tcp(std::string str, std::string ip, int port) {int send_len = 0;// 初始化套接字库initialization();//填充服务端信息service_TCP_to.sin_family = AF_INET;service_TCP_to.sin_addr.S_un.S_addr = inet_addr(ip.c_str());service_TCP_to.sin_port = htons(port);//创建套接字SendSocket_TCP_to = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (SendSocket_TCP_to == INVALID_SOCKET) {logger->error("创建套接字失败:" + WSAGetLastError());std::cout << "创建套接字失败:" << WSAGetLastError() << std::endl;WSACleanup();exit(1);}if (connect(SendSocket_TCP_to, (SOCKADDR*)&service_TCP_to, sizeof(SOCKADDR)) == SOCKET_ERROR) {std::cout << "服务器连接失败:" << WSAGetLastError() << std::endl;logger->error("服务器连接失败:" + WSAGetLastError());WSACleanup();exit(1);}// 发送信息send_len = send(SendSocket_TCP_to, str.c_str(), str.size(), 0);if (send_len < 0) {std::cout << "发送失败:" << WSAGetLastError() << std::endl;logger->error("发送失败:" + WSAGetLastError());}std::cout << send_len << "发送成功" << std::endl;//关闭套接字//closesocket(SendSocket_TCP_to);//释放DLL资源//WSACleanup();
}void SocketManager::get_from_tcp(int port) {// 初始化套接字库initialization();// 创建套接字ListenSocket_TCP_get = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   // tcp与udp之间有所不同if (ListenSocket_TCP_get == INVALID_SOCKET) {logger->error("创建套接字失败:" + WSAGetLastError());std::cout << "创建套接字失败:" << WSAGetLastError() << std::endl;WSACleanup();exit(1);}//填充服务端信息service_TCP_get.sin_family = AF_INET;  // 设置地址族为 IPv4service_TCP_get.sin_addr.s_addr = INADDR_ANY;  // 将 IP 地址设置为 0.0.0.0,表示绑定到所有本地 IP 地址service_TCP_get.sin_port = htons(port);   // 将端口号转换为网络字节序,并设置为指定的端口号// 绑定套接字if (bind(ListenSocket_TCP_get, (SOCKADDR*)&service_TCP_get, sizeof(service_TCP_get)) == SOCKET_ERROR){logger->error("绑定套接字失败: " + WSAGetLastError());std::cout << "绑定套接字失败: " + WSAGetLastError() << std::endl;closesocket(ListenSocket_TCP_get);WSACleanup();exit(1);}char recvbuf[512];  // 定义接收信息的缓冲区,大小为512字节int iRecvResult;  // 存储接收操作的返回结果int len = 0;//设置套接字为监听状态if (listen(ListenSocket_TCP_get, SOMAXCONN) < 0) {std::cout << "设置监听状态失败:" << WSAGetLastError() << std::endl;logger->error("设置监听状态失败:" + WSAGetLastError());WSACleanup();}std::cout << "服务端正在监听连接,请稍候...." << std::endl;len = sizeof(service_TCP_get);SOCKET ClientSocket = INVALID_SOCKET;  // 初始化 ClientSocket 变量并将其设置为无效的套接字do{std::cout << "服务端正在等待数据发送,请稍候...." << std::endl;ClientSocket = accept(ListenSocket_TCP_get, (SOCKADDR*)&service_TCP_get, &len); // 等待客户端连接请求并接受连接/*accept 函数会阻塞,直到有客户端连接请求到达,然后返回一个新的套接字ListenSocket_TCP_get 是服务器监听的套接字service_TCP_get 是用于存储客户端地址信息的结构体len 是地址结构体的大小,accept 函数调用时会被更新为实际的地址大小*/// std::cout << ClientSocket << std::endl;if (ClientSocket == SOCKET_ERROR) {std::cout << "算法端连接失败:" + WSAGetLastError() << std::endl;logger->error("算法端连接失败:" + WSAGetLastError());WSACleanup();exit(2);}// 接收来自客户端的数据iRecvResult = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0);// 检查接收操作是否成功if (iRecvResult > 0){// std::cout << iRecvResult << std::endl;std::string result(recvbuf, iRecvResult);std::cout << "收到信息:" + result << std::endl;logger->info("收到信息:" + result);// 将接收到的数据发送回客户端// sendto(ListenSocket_UDP, recvbuf, iRecvResult, 0, (SOCKADDR*)&clientAddr, sizeof(clientAddr));}else if (iRecvResult == 0){std::cout << "连接关闭" << std::endl;logger->info("连接关闭");}else{std::cout << "接受信息失败:" << WSAGetLastError() << std::endl;logger->error("接受信息失败:" + WSAGetLastError());closesocket(ListenSocket_UDP_get);WSACleanup();}} while (iRecvResult > 0);closesocket(ListenSocket_TCP_get);WSACleanup();
}void SocketManager::send_to_udp(std::string str, std::string ip, int port) {int send_len = 0;// 初始化套接字库initialization();//填充服务端信息service_UDP_to.sin_family = AF_INET;service_UDP_to.sin_addr.S_un.S_addr = inet_addr(ip.c_str());service_UDP_to.sin_port = htons(port);//创建套接字SendSocket_UDP_to = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if (SendSocket_UDP_to == INVALID_SOCKET) {logger->error("创建套接字失败:" + WSAGetLastError());std::cout << "创建套接字失败:" << WSAGetLastError() << std::endl;WSACleanup();exit(0);}int iSendResult = sendto(SendSocket_UDP_to, str.c_str(), str.size(), 0, (SOCKADDR*)&service_UDP_to, sizeof(service_UDP_to));if (iSendResult == SOCKET_ERROR) {std::cout << "发送失败:" << WSAGetLastError() << std::endl;logger->error("发送失败:" + WSAGetLastError());}//关闭套接字closesocket(SendSocket_UDP_to);//释放DLL资源WSACleanup();
}std::string asciiToHex(const std::string& asciiStr) {std::string hexStr;for (char c : asciiStr) {unsigned char value = static_cast<unsigned char>(c);hexStr += std::to_string(static_cast<int>(value >> 4)) + std::to_string(static_cast<int>(value & 0x0F));}return hexStr;
}

http://www.lryc.cn/news/403376.html

相关文章:

  • Nest.js 实战 (三):使用 Swagger 优雅地生成 API 文档
  • spark shell
  • 集群架构-web服务器(接入负载均衡+数据库+会话保持redis)--15454核心配置详解
  • # Redis 入门到精通(七)-- redis 删除策略
  • 10:00面试,10:08就出来了,问的问题有点变态。。。
  • html+canvas 实现签名功能-手机触摸
  • 前端组件化探索与实践:Vue自定义暂无数据组件的开发与应用
  • 《汇编语言 基于x86处理器》- 读书笔记 - Visual Studio 2019 配置 MASM环境
  • Air780E/Air780EP/Air780EQ/Air201模块遇到死机问题如何分析
  • 吴松洋院长 艺后整形集团专家组特约成员 全方位责任塑美
  • 前端经验:使用sheetjs导出CSV文本为excel
  • 【nnUNetv2进阶】十五、nnUNetv2 魔改网络-小试牛刀-引入ECA
  • centos(或openEuler系统)安装kafka集群
  • HarmonyOS根据官网写案列~ArkTs从简单地页面开始
  • GraphRAG+ollama+LM Studio+chainlit
  • 【中项第三版】系统集成项目管理工程师 | 第 5 章 软件工程② | 5.4 - 5.8
  • 6. dolphinscheduler-3.0.0伪集群部署
  • 防火墙内容安全综合实验
  • 常见的数据分析用例 —— 信用卡交易欺诈检测
  • IP地址:由电脑还是网线决定?
  • 如何定位及优化SQL语句的性能
  • SentenceTransformers (SBERT)
  • 第三届智能机械与人机交互技术学术会议(IHCIT 2024)
  • 图的访问(C++)
  • LeetCode做题记录(第二天)169. 多数元素
  • Adobe XD中文设置指南:专业设计师的现场解答
  • CentOS 7 安装Jenkins2.346.1(war方式安装)
  • 使用Java -jar运行就jar包时报异常:org.yaml.snakeyaml.error.YAMLException异常
  • golang实现的ab测试http代理工具
  • Maven学习——Maven的下载、安装与配置(详细攻略!)