14.6 Socket 应用结构体传输

news2024/11/24 6:00:03

当在套接字编程中传输结构体时,可以将结构体序列化为字符串(即把结构体的所有成员打包成一个字符串),然后将字符串通过套接字传输到对端,接收方可以将字符串解析为结构体,然后使用其中的成员数据。这种方法通常被称为序列化(Serialization)和反序列化(Deserialization),本章中我们可以采用将一个结构体序列化为一个纯字符串,然后将该字符串通过套接字传输给对端,当对端收到后只需要将字节序强制转换为对等的结构体指针即可实现对该结构的解析。

14.6.1 服务端实现

首先来看服务端的实现流程,笔者定义了message结构体变量,代码中在接收到套接字传输过来的字符串之后,通过(message*)recv_buf的方式将该套接字强制转换为一个结构体指针,并赋值给message* msg指针,此时在服务端则可通过->的方式输出当前结构体内的完整成员参数。

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

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

// 定义一个自定义结构体
typedef struct
{
  unsigned short uuid;
  char HostName[32];
  char Buffer[32];

  struct
  {
    char HostAddress[1024];
    char HostPassword[1024];
    char HostPort[1024];
  }HostInfo;

  unsigned short cmd_type;
}message;

int main(int argc, char* argv[])
{
  WSADATA WSAData;
  SOCKET sock;

  WSAStartup(MAKEWORD(2, 0), &WSAData);
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock == INVALID_SOCKET)
  {
    std::cout << "创建套接字失败" << std::endl;
  }

  struct sockaddr_in ServerAddr;
  ServerAddr.sin_family = AF_INET;
  ServerAddr.sin_port = htons(9999);
  ServerAddr.sin_addr.s_addr = INADDR_ANY;

  // 绑定套接字
  auto res = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));
  if (res == SOCKET_ERROR)
  {
    std::cout << "绑定失败" << std::endl;
  }

  // 侦听套接字
  res = listen(sock, 10);
  if (res == SOCKET_ERROR)
  {
    std::cout << "侦听失败" << std::endl;
  }

  SOCKET msgsock;

  // 用于接收结构
  char recv_buf[4096] = { 0 };

  msgsock = accept(sock, (LPSOCKADDR)0, (int*)0);
  if (msgsock != INVALID_SOCKET)
  {
    recv(msgsock, recv_buf, sizeof(recv_buf), 0);

    // 接收到结构,强制类型转换
    message* msg = (message*)recv_buf;

    std::cout << "ID: " << msg->uuid << " 主机名: " << msg->HostName
      << " 数据包: " << msg->Buffer << " 主机地址: " << msg->HostInfo.HostAddress
      << "主机密码: " << msg->HostInfo.HostPassword << std::endl;
  }

  closesocket(sock);
  WSACleanup();
  return 0;
}

14.6.2 客户端实现

对于客户端来说,在定义好全局message结构体之后直接通过字符串拷贝方法实现对全局结构的填充,当全局结构体被填充后直接使用memcpy(send_buf, &msg, sizeof(message))将该结构体的字节拷贝到send_buf这个缓冲区内,最后调用send()发送这段缓冲区即可实现。

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

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

// 定义一个自定义结构体
typedef struct
{
  unsigned short uuid;
  char HostName[32];
  char Buffer[32];

  struct
  {
    char HostAddress[1024];
    char HostPassword[1024];
    char HostPort[1024];
  }HostInfo;

  unsigned short cmd_type;
}message;

// 定义变量
message msg;

int main(int argc, char* argv[])
{
  WSADATA WSAData;
  SOCKET sock;

  WSAStartup(MAKEWORD(2, 0), &WSAData);
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock == INVALID_SOCKET)
  {
    std::cout << "创建套接字失败" << std::endl;
  }

  struct sockaddr_in ClientAddr;
  ClientAddr.sin_family = AF_INET;
  ClientAddr.sin_port = htons(9999);
  ClientAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  // 链接对端
  auto res = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
  if (res == SOCKET_ERROR)
  {
    std::cout << "链接失败." << std::endl;
  }

  // 首先需要定义一个变量
  char send_buf[4096] = { 0 };

  // 拷贝外部变量
  msg.uuid = 1001;
  strcpy(msg.HostName, "lyshark PC");
  strcpy(msg.Buffer, "hello world");

  // 拷贝内部HostInfo
  strcpy(msg.HostInfo.HostAddress, "192.168.1.1");
  strcpy(msg.HostInfo.HostPassword, "12345678");
  strcpy(msg.HostInfo.HostPort, "8888");

  // 拷贝内部Type
  msg.cmd_type = 1;

  // 发送字节序
  memcpy(send_buf, &msg, sizeof(message));
  send(sock, send_buf, sizeof(send_buf), 0);

  closesocket(sock);
  WSACleanup();
  return 0;
}

运行上述代码片段,读者可看到结构体已被正确的传输给服务端,效果图如下所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/a71d879b.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

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

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

相关文章

如何提高企业工作微信的管理效率?

微信作为一款拥有数亿用户的软件&#xff0c;其使用频率在全国范围内居高不下。随着企业的不断发展&#xff0c;微信在工作中的应用也变得越来越广泛。为了更好地服务客户并提升业务效益&#xff0c;企业通常会为新入职员工配置工作微信以便于业务沟通和客户服务。然而&#xf…

推荐系统离线评估方法和评估指标,以及在推荐服务器内部实现A/B测试和解决A/B测试资源紧张的方法。还介绍了如何在TensorFlow中进行模型离线评估实践。

文章目录 &#x1f31f; 离线评估&#xff1a;常用的推荐系统离线评估方法有哪些&#xff1f;&#x1f34a; 1. RMSE/MSE&#x1f34a; 2. MAE&#x1f34a; 3. Precision/Recall/F1-score&#x1f34a; 4. Coverage&#x1f34a; 5. Personalization&#x1f34a; 6. AUC &…

ChatGPT当导购员!全球最大超市,全面应用生成式AI

全球最大连锁超市沃尔玛&#xff08;Walmart&#xff09;在官网宣布&#xff0c;将在电商平台试用3款生成式AI&#xff0c;帮助用户改善购物体验提升效率。 据悉&#xff0c;沃尔玛使用了一种类ChatGPT的产品&#xff0c;可根据文本提示自动生成购物建议、搜索建议和评论摘要等…

客流人数管理新趋势:景区客流采集分析系统的功能特点

随着旅游业的蓬勃发展&#xff0c;越来越多的人选择前往景区进行休闲和旅游。然而&#xff0c;人流量的增加也给景区管理带来了一系列的挑战。为了更好地管理和运营景区&#xff0c;景区客流采集分析系统应运而生。 一、案例展示 二、产品卖点 该系统利用先进的人工智能算法和…

今天面了一个来华为要求月薪23K,明显感觉他背了很多面试题...

最近有朋友去华为面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

IDEA初始配置

1. 详细设置 安装完IDEA之后的简单配置。 1.1 如何打开详细配置界面 1、显示工具栏 2、选择详细配置菜单或按钮 1.2 系统设置 1、默认启动项目配置 启动IDEA时&#xff0c;默认自动打开上次开发的项目&#xff1f;还是自己选择&#xff1f; 如果去掉Reopen projects on …

ABB REM615 REM611 人工智能和机器学习

ABB REM615 REM611 人工智能和机器学习 自从围绕ChatGPT的炒作开始&#xff0c;每个人都在谈论生成性AI。德国人工智能公司Aleph Alpha的ChatGPT、DALL-E或Luminous等系统今天已经能够支持文本写作、编程和设计。 Aleph Alpha在汉诺威工业博览会上更进一步:该公司将与惠普公司…

许战海战略文库|2023,小鹏危矣!蔚小理之江湖点评

摘要&#xff1a;“性价比”与“主流化”之路的竞争关键是产业链整体优势,中国拥有新能源产业链优势的整车企业,只有比亚迪和长城汽车。 1 月 18 日&#xff0c;何小鹏在小鹏汽车内部喊出“如果不破&#xff0c;小鹏只是早死和晚死的区别。要么跟大家一起足够精彩&#xff0c;要…

Go编程:使用 Colly 库下载Reddit网站的图像

概述 Reddit是一个社交新闻网站&#xff0c;用户可以发布各种主题的内容&#xff0c;包括图片。本文将介绍如何使用Go语言和Colly库编写一个简单的爬虫程序&#xff0c;从Reddit网站上下载指定主题的图片&#xff0c;并保存到本地文件夹中。为了避免被目标网站反爬&#xff0c…

过关斩将法:验证输入的用户信息:

输入用户名、密码、邮箱、如果信息录入正确&#xff0c;则提示注册成功&#xff0c;否则生成异常&#xff1a; 要求&#xff1a; 用户名长度为2或3或4密码的长度为6&#xff0c;要求全是数字 提示&#xff1a;可以自行设计isDigital方法&#xff0c;否则排版则乱邮箱中包含和…

Steam余额红锁的原因,及红锁后申诉办法

安全的余额一般是通过充值卡充值获得&#xff0c;再加上交易手续费再转卖给你。一般便宜不到哪去。 但你别以为余额是安全的&#xff0c;就万事大吉了。照样有被红锁的可能性&#xff0c;比如这三种&#xff1a; 1、Steam市场巡查机制&#xff0c;红锁 平台的巡查机制和原理…

【PCIe Byte Enable】

PCIe Byte Enable 及与TPH关系 Byte Enable PCIe Byte Enable 在mem/IO/Cfg TLP中被应用并且在各种不同TLP中的没有区别&#xff0c;PCIe中Byte Enable与AXI中wstrb类似起到mask的作用&#xff0c;但是PCIe不支持request数据全部字节的mask&#xff0c;只支持数据头和尾部各一…

ASEMI解读KBL610整流桥的使用说明及操作指南

编辑-Z KBL610整流桥是一种功率电子元件&#xff0c;它在电力系统、电力电子设备中有着广泛的应用。然而&#xff0c;对于初次接触或者专业人士来说&#xff0c;明确使用说明和操作更是关键。那么&#xff0c;让我们一起来详解KBL610整流桥的使用说明及操作指南。 KBL610整流桥…

灾害与环境遥感团队本科生在IEEE TGRS 发表高水平论文

2023年9月27日&#xff0c;地球科学和遥感领域顶级期刊《IEEE Transactions on Geoscience and Remote Sensing》&#xff08;IEEE TGRS&#xff09;在线预刊发了灾害与环境遥感团队的最新研究成果“A novel spectral index for rapid dust-proof net mapping based on Sentine…

COLE HERSEE 48408 工业4.0、制造业X和元宇宙

COLE HERSEE 48408 工业4.0、制造业X和元宇宙 需要数据来释放工业4.0的全部潜力——价值链中的所有公司都可以访问大量数据。一个新的互联数据生态系统旨在提供解决方案:制造业x。 在德国联邦经济事务和气候行动部以及BDI、VDMA和ZVEI贸易协会的密切合作下&#xff0c;实施制…

性能测试之Mysql数据库调优

一、前言 性能调优前提&#xff1a;无监控不调优&#xff0c;对于mysql性能的监控前几天有文章提到过&#xff0c;有兴趣的朋友可以去看一下 二、Mysql性能指标及问题分析和定位 1、我们在监控图表中关注的性能指标大概有这么几个&#xff1a;CPU、内存、连接数、io读写时间…

一文了解多模态数字人

一、什么是多模态数字人 多模态数字人是一种通过多种传感器获取人体数据&#xff0c;使用计算机技术进行处理和分析&#xff0c;构建出具有多种感知和交互能力的虚拟人。多模态数字人可以通过视觉、听觉、触觉等多种感知方式与人类进行交互&#xff0c;具有高度的仿真度和个性…

Java基础20问(1-5)

1.Java面向对象和面试过程的区别&#xff1f; 面向过程是将一个问题拆解成几个步骤&#xff0c;依次实现每一个步骤&#xff0c;比如实现一个冒泡排序的算法&#xff0c;是为了解决某个非常具体的问题。 而面向对象也是将一个问题拆解成几个步骤&#xff0c;但是先不去实现&a…

华为云云耀云服务器L实例评测|企业项目最佳实践之评测用例(五)

华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践系列&#xff1a; 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之云服务器介绍(一) 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之华为云介绍(二) 华为云云耀云服务器L实例评测&#xff5…

B端设计的核心:助你成功的关键!

B端设计是指针对企业、组织、机构等机构客户的设计服务&#xff0c;通常称为“企业级设计”或“商业设计”&#xff0c;而不是针对消费者的C端设计。B端设计是一个旨在实现企业商业目标的设计过程&#xff0c;旨在满足企业客户的需求&#xff0c;帮助他们增强市场竞争力&#x…