发送结构化的网络消息数据

news2025/5/19 15:59:04

 server.cpp

#define WIN32_LEAN_AND_MEAN //尽力减少一些其他依赖库的引用
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include<windows.h>
#include<WinSock2.h>
#include<stdio.h>
//#pragma comment(lib,"ws2_32.lib")

struct DataPackage {
	int age;
	char name[32];
};

int main() {
	WORD ver = MAKEWORD(2, 2);
	WSADATA dat;
	WSAStartup(ver, &dat);
	//----------------------
	
	// -- 用Socket API建立简易TCP服务端
	// 1 建立一个socket 套接字(地址族规范、新套接字的类型规范、要使用的协议 )
	SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	// 2 bind 绑定用于接受客户端连接的网络端口
	sockaddr_in _sin = {};
	_sin.sin_family = AF_INET;
	_sin.sin_port = htons(4567);//host to net unsigned short
	_sin.sin_addr.S_un.S_addr = INADDR_ANY;//inet_addr("127.0.0.1");
	//bind(_sock, (sockaddr *)& _sin, sizeof(_sin));//​作用:给socket绑定端口号与具体位置
	if (SOCKET_ERROR == bind(_sock,(sockaddr*)&_sin,sizeof(sockaddr_in))) {
		printf("错误,绑定网络端口失败...\n");
	}
	else {
		printf("绑定网络端口成功...\n");
	}

	// 3 listen 监听网络端口
	//listen(_sock, 5);
	if (SOCKET_ERROR == listen(_sock, 5)) {
		printf("错误,监听网络端口失败...\n");
	}
	else {
		printf("监听网络端口成功...\n");
	}

	// 4 accept 等待接受客户端连接
	sockaddr_in clientAddr = {};
	int nAddrLen = sizeof(sockaddr_in);
	SOCKET _cSock = INVALID_SOCKET;

	_cSock = accept(_sock, (sockaddr*)&clientAddr, &nAddrLen);
	if (INVALID_SOCKET == _cSock) {
		printf("错误,接收到无效客户端SOCKET...\n");
	}
	printf("新客户端加入:socket = %d, IP = %s \n", (int)_cSock, inet_ntoa(clientAddr.sin_addr));

	char _recvBuf[128] = {};
	while (true) {
		// 5 接收客户端的数据
		int nLen = recv(_cSock, _recvBuf, 128, 0);
		if (nLen <= 0) {
			printf("客户端已退出,任务结束...");
			break;
		}
		printf("收到命令:%s \n",_recvBuf);
		// 6 处理请求
		if (0 == strcmp(_recvBuf,"getInfo")) {
			// 7 send 向客户端发送一条数据
			DataPackage dp = {18,"呵呵哒"};
			send(_cSock, (const char *)&dp, sizeof(DataPackage), 0);
		}
		else {
			char msgBuf[] = "???????????????????...";
			// 7 send 向客户端发送一条数据 
			send(_cSock, msgBuf, strlen(msgBuf) + 1, 0);
		}
		
	}

	// 6 关闭套接字closesocket 
	closesocket(_sock);
	//----------------------

	//清除Windows socket环境
	WSACleanup();
	printf("已退出...");
	getchar();
	return 0;
}

//严重性	代码	说明	项目	文件	行	禁止显示状态
//错误	C4996	'inet_ntoa': Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings	EasyTcpServer	E : \net_c++\EasyTcpServer\server.cpp	51
//解决方案:#define _WINSOCK_DEPRECATED_NO_WARNINGS

client.cpp

#define WIN32_LEAN_AND_MEAN //尽力减少一些其他依赖库的引用
//#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include<windows.h>
#include<WinSock2.h>
//#pragma comment(lib,"ws2_32.lib")
#include<stdio.h>

struct DataPackage {
	int age;
	char name[32];
};

int main() {
	WORD ver = MAKEWORD(2, 2);
	WSADATA dat;
	WSAStartup(ver, &dat);
	//----------------------
	
	//-- 用Socket API建立简易TCP客户端
	// 1 建立一个Socket
	SOCKET _sock = socket(AF_INET,SOCK_STREAM,0);
	if (INVALID_SOCKET == _sock) {
		printf("错误,建立Socket失败...\n");
	}
	else {
		printf("建立Socket成功...\n");
	}
	// 2 连接服务器 connect
	sockaddr_in _sin = {};
	_sin.sin_family = AF_INET;
	_sin.sin_port = htons(4567);
	_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	int ret = connect(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in));
	if (SOCKET_ERROR == ret) {
		printf("错误,连接服务器失败...\n");
	}
	else {
		printf("连接服务器成功...\n");
	}

	while (true) {
		//3 输入请求命令
		char cmdBuf[128] = {};
		scanf("%s",cmdBuf);
		//4 处理请求
		if (0 == strcmp(cmdBuf, "exit")) {
			printf("收到exit命令,任务结束...");
			break;
		}
		else {
			//5 向服务器发送请求命令
			send(_sock, cmdBuf, strlen(cmdBuf) + 1, 0);
		}
		// 6 接收服务器信息 recv
		char recvBuf[256] = {};
		int nlen = recv(_sock, recvBuf, 256, 0);
		if (nlen > 0) {
			DataPackage* dp = (DataPackage *)recvBuf;//这样简单的转化有点不安全
			printf("接收到数据:年龄 = %d ,姓名 = %s \n", dp->age,dp->name);
		}
	}
	
	// 4关闭套接字 closesocket
	closesocket(_sock);
	
   //---------------------- 
	//清除Windows socket环境
	WSACleanup();
	printf("已退出...");
	getchar();
	return 0;
}

//严重性	代码	说明	项目	文件	行	禁止显示状态
//错误	C4996	'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings	EasyTcpClient	E : \net_c++\EasyTcpClient\client.cpp	26

运行效果:

 

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

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

相关文章

HTTP Keep-Alive模式

故事发生在10月份的一次面试经历中&#xff0c;本来我不想说出来丢人显眼&#xff0c;但是为了警醒自己和告诫后人&#xff0c;我决定写成博文发出来。因为在面试过程中&#xff0c;我讲在2009年写过QQ农场助手&#xff0c;在这期间深入学习了HTTP协议&#xff0c;而且在2010-0…

盐湖钛系提锂吸附剂

#盐湖钛系提锂吸附剂 盐湖钛系提锂吸附剂HPL900是一种高选择性高容量锂离子筛吸附剂。其通过纳米杂化、锂离子印迹等技术制备而成。该吸附剂活性纳米晶粒子对锂离子具有高效吸附性能&#xff08;其对锂的吸附容量大于10.0g Li/L&#xff09;&#xff0c;同时吸附位点对锂离子具…

哈希表(底层结构剖析-- 上)

文章目录 哈希表底层结构剖析哈希概念哈希冲突哈希函数 哈希冲突解决办法闭散列( 线性探测 二次探测)开散列 哈希表闭散列方法的模拟实现基本框架有关哈希数据的类插入函数删除函数查找函数增加仿函数将所有数据类型转换为整型 哈希表开散列方法的模拟实现(增加仿函数版) 哈希…

Visual Studio的安装注意

本文目前包含的内容&#xff1a; Visual Studio版本选择工作负载组建的选择安装后的环境配置 目录 1. 安装前1. 安装过程中2. 安装后注意 1. 安装前 安装版本选择&#xff1a; 一定不要选最新的版本&#xff0c;选3-5年前的稳定版本&#xff01;新版本会出很多bug。 1. 安装过…

银行数字化转型导师坚鹏:银行数字化转型创新与应用前沿

银行数字化转型创新与应用前沿 ——金融科技如何赋能银行数字化转型 课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a; 不清楚5G如何赋能银行数字化转型&#xff1f; 不清楚最新金融科技如何赋能银行数字化转型&#xff1f; 不了解银行…

自动驾驶落地如何降本?这家头部公司有自己的独特之处

一直以来&#xff0c;商用车智能化与乘用车有很多差异化&#xff0c;比如&#xff0c;B端客户对于规模车队的采购成本&#xff0c;智能化应用场景的适配性以及对自动驾驶更为务实的认知。 4月18日&#xff0c;2023上海车展&#xff0c;作为场景化新能源的自动驾驶全球领导者&am…

直播软件app开发:如何开发一个可以免费打扑克的直播应用?

作为一个技术开发人员&#xff0c;我深知直播软件app开发的重要性。在这个数字化时代&#xff0c;越来越多的人选择使用直播软件来分享自己的生活和与朋友互动。而随着技术的发展&#xff0c;直播软件也不断更新和改进&#xff0c;为用户提供更好的体验和功能。 对于开发者来说…

git merge、git pull和git fetch

git merge 合并分支&#xff0c;将目标分支合并到当前分支git fetch 更新远端分支&#xff0c;但不会merge到本地git pull 更新远端分支并merge到本地git pull git fecth git merge merge的意思为“合并”&#xff0c;git merge命令是用于将分支合并在一起的操作&#xff…

kafka_2.13-2.8.1环境搭建

本次kafka环境主要针对kafka2.x版本&#xff0c;运行kafka服务之前&#xff0c;需要先搭建zookeeper服务&#xff0c;因为kafka服务依赖zookeeper&#xff0c;kafka3.x版本后可以不需要手动搭建zookeeper了。 本文主要是介绍怎样搭建kafka2.8.1&#xff0c;关于kafka的操作&am…

matlab求解整数规划

一、整数规划 定义&#xff1a;数学规划中的变量&#xff08;部分或全部&#xff09;限制为整数时&#xff0c;称为整数规划。 若在线性规划模型中&#xff0c;变量限制为整数&#xff0c;则称为整数线性规划。 分类&#xff1a;&#xff08;1&#xff09;变量全部限制为整数时…

JUC多并发编程 内存模型

计算机硬件存储系统 因为有多级的缓存(CPU 和 物理主内存的速度不一致的)&#xff0c; CPU 的运行并不是直接操作内存耳饰先把内存里边的数据读到缓存&#xff0c;而内存的读和写操作的时候就会造成不一致的问题JVM 规范中试图定义一种 Java 内存模型(Java Memory Model, 简称…

【UE】倒计时归零时结束游戏

上一篇博客&#xff08;【UE】一个简易的游戏计时器&#xff09;完成了游戏时间每秒1的功能&#xff0c;本篇博客在此基础上完成倒计归零时结束游戏的功能 效果 步骤 1. 打开“ThirdPersonGameMode”&#xff0c;将剩余的秒数和分钟数的默认值分别设置为1和59 在事件图表中添…

全球首款车规级彩色激光大灯,这家中国供应商引领下一代显示交互

随着汽车智能化进程进入深水区&#xff0c;基于显示、照明的新技术正在成为新的聚焦点。无论是AR HUD&#xff0c;还是舱内多模态人机交互都在成为新的增量。而汽车独有的智能移动终端以及第三生活空间的未来属性&#xff0c;也在创造新的市场机会。 4月18日&#xff0c;全球领…

法规标准-ISO 16787标准解读

ISO 16787是做什么的&#xff1f; ISO 16787全称为智能运输系统-辅助泊车系统&#xff08;APS&#xff09;-性能要求和测试程序&#xff0c;其中主要描述了对APS系统的功能要求及测试规范 APS类型 根据目标停车位类型将APS系统分为两类&#xff1a; 1&#xff09;APS类型I&a…

北大POJ 1000 ~ 1009

1. AB &#x1f351; POJ1000 ab &#x1f354; 签到题 import java.io.*; import java.util.*; public class Main {public static void main(String args[]) throws Exception{Scanner cinnew Scanner(System.in);int acin.nextInt(),bcin.nextInt();System.out.println(…

开发常用的 Linux 命令3(文本处理、打包和压缩)

开发常用的 Linux 命令3&#xff08;文本处理、打包和压缩&#xff09; 作为开发者&#xff0c;Linux是我们必须掌握的操作系统之一。因此&#xff0c;在编写代码和部署应用程序时&#xff0c;熟练使用Linux命令非常重要。这些常用命令不得不会&#xff0c;掌握这些命令&#…

c提高学习——指针作为函数参数的输入特性

输入特性 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> //在主调函数分配内存 被调函数使用 void func(char *p) {strcpy(p, "hello world"); } void test01() {//在栈上分配内存char buf[1024] …

《使用循环做一些练习》---C语言

目录 前言&#xff1a; 1.练习专题 1.1打印1-100之间的奇数 1.2计算n的阶乘 1.3计算到达n阶乘的前m个阶乘相加 1.4演示字符串动态变化的效果 2.goto语句 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础…

扬声器,打印机2键触摸VK3602K SOP8 2键2通道触摸检测芯片技术资料直接输出自动校准功能

型号&#xff1a;VK3602K 封装形式&#xff1a;SOP8 KPP2620 VK3602K具有2个触摸按键&#xff0c;可用来检测外部触摸按键上人手的触摸动作。该芯片具有较高的集成度&#xff0c;仅需极少的外部组件便可实现触摸按键的检测。 提供了2路直接输出功能,可通过IO脚选择输出电平。…

基于单片机的家庭防盗报警系统的设计与实现_kaic

基于单片机的家庭防盗报警系统 专业&#xff1a;物联网工程 摘要&#xff1a;本论文研究的是将AT89C52单片机芯片作为核心元器件的防盗报警系统,该系统除了具有直接报警的功能外,还额外增加了布防和红外感应的功能。和市场上的其他各类防盗报警器相比,该设计的不同之处在于它所…