首页 > 编程语言 >C++ - tcp网络传输如何发送结构体类型

C++ - tcp网络传输如何发送结构体类型

时间:2024-05-29 11:32:59浏览次数:14  
标签:发送 int send C++ char 传输 tcp sizeof 结构

1、tcp网络传输如何发送结构体类型

 在C++中,要通过TCP网络传输结构体类型,你需要将结构体序列化为字节流,然后在另一端反序列化。这里有一个简单的例子:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
 
// 假设的结构体
struct MyStruct {
    int id;
    float value;
    // 序列化函数
    char* serialize() const {
        char* buffer = new char[sizeof(MyStruct)];
        memcpy(buffer, &this->id, sizeof(int));
        memcpy(buffer + sizeof(int), &this->value, sizeof(float));
        return buffer;
    }
    // 反序列化函数
    void deserialize(char* buffer) {
        memcpy(&this->id, buffer, sizeof(int));
        memcpy(&this->value, buffer + sizeof(int), sizeof(float));
    }
};
 
int main() {
    int sockfd;
    struct sockaddr_in servaddr;
 
    // 创建socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
 
    // 服务器地址
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(1234);
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
 
    // 连接服务器
    connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
 
    // 创建结构体实例
    MyStruct obj = {123, 3.14f};
 
    // 序列化并发送
    char* buffer = obj.serialize();
    send(sockfd, buffer, sizeof(MyStruct), 0);
    delete[] buffer;
 
    // 接收并反序列化
    char recvBuffer[sizeof(MyStruct)];
    recv(sockfd, recvBuffer, sizeof(recvBuffer), 0);
    MyStruct receivedObj;
    receivedObj.deserialize(recvBuffer);
 
    // 输出接收到的结构体成员
    std::cout << "Received ID: " << receivedObj.id << ", Value: " << receivedObj.value << std::endl;
 
    // 关闭socket连接
    close(sockfd);
    return 0;
}

 在这个例子中,MyStruct 结构体包含了两个成员:id 和 valueserialize 函数将结构体转换为字节流,而 deserialize 函数从字节流中恢复结构体。

在实际的TCP通信过程中,你需要确保发送和接收方的序列化和反序列化方式完全一致,以正确地重建结构体数据。

 

 

2、TCP-socket发送结构体类型数据

UDP传输模式是数据报,TCP传输模式为字节流,字节流与数据报区别在于有边界与无边界。例如:TCP客户端发送了三个数据包,开的缓存足够大服务端一次可接收三个数据包的数据,这就是无边界。UDP客户端发送了三个数据包,就算开的缓存足够大服务端一次也只能接收一个数据包,这就是有边界。

还有就是协议会维护源地址和目的地址直到协议要求断开连接,这就决定了TCP不能进行广播和多播。

如何使用TCP发送结构体类型数据:

·     //使用结构体转换成字符串发送,在服务器端直接转为结构体  

·     /*  

·     char send_buf[1024] = "tony  2000  ";  

·     memset(send_buf,0,1024);  

·     struct msg  

·     {  

·         int cmd;  

·         int sendID;  

·         int recvID;  

·         string name;  

·         int number;  

·     };  

·     msg msg1;  

·     msg1.cmd = COMMAND;  

·     msg1.sendID = 2120100324;  

·     msg1.recvID = 2120100325;  

·     msg1.name = "Tony";  

·     msg1.number = 2000;  

·       

·   

·     //以字符串形式发送,因为TCP/IP是字节流通信  

·     //memcpy(send_buf,&msg1,sizeof(msg));  

·     //int len_send = send(Socket,send_buf,sizeof(send_buf),0);  

·     int len_send = send(Socket,(char *)&msg1,sizeof(msg),0);  

如上所示,

TCP是无边界的字节流传输,所以需要将结构体转换为字符串后在发送,最后三行用了两种方法发送属于结构体类型的数据,通过TCP传输。最后在接收方需要转换为结构体。

红色:  数组属于字符串,该方法是将要发送结构体所占字节大小考到数组中,       再通过数组发送。

蓝色:  将该结构体地址转化为char* 类型的地址,目的是使该指针加1移动时 是按一个字节移动,而不是加1按该结构体大小移动,然后发送该结构 体所占字节大小。

 

 

3、C++ socket 传输不同类型的数据

1.1 使用结构体

I.假设需要传输的结构体数据如下:

注意:(发送方和接收方都需要定义相同的结构体)

 
struct Student
{
	int iId;
	string strName;
	bool bSex;    //为了节省内存空间,性别采用一个字节的BOOL类型表示
};

   

II.发送方代码(客户端)

 
struct Student stu;    //声明一个Student结构体变量
stu.iId = 1001;
stu.bSex = true;       //true表示男性,false表示女性,你反过来也行,别打拳
stu.strName = "abcdefzzzzz";
 
//下面的m_sclient是客户端(发送方)的Socket套接字
 
//方法一:推荐如下
send(m_sclient, (char*)&stu, sizeof(Student), 0);//&stu取stu地址,(char*)转化为char类型的指针
 
//方法二:或者增加一个中间变量sendBuff[]来传送,如下
//char sendBuff[1024];
//memset(sendBuff,0,sizeof(sendBuff));
//memcpy(sendBuff, &stu, sizeof(Student));
//send(m_sclient, sendBuff, sizeof(sendBuff), 0);

 

III.接收方代码(服务端)

 
struct Student stu;    //声明一个结构体变量,用于接收客户端(发送方)发来的数据
char buffFromClient[1024];    //用于临时接收发送方的数据
//方法一:(推荐)
recv(clientSocket, (char*)&stu, sizeof(Student), 0);
 
//方法二:
//memset(buffFromClient,0,sizeof(buffFromClient));
//recv(clientSocket, buffFromClient, sizeof(Student), 0);
//memset(&stu,buffFromClent,sizeof(Student));

 

 

1.2 使用类对象

I.添加StudentInfo类

注意:(发送方和接收方都需要定义相同结构的类对象)

 

 
//StudentInfo.h文件如下,.cpp文件自行实现
 
#pragma once
#include <iostream>
using namespace std;
class StudentInfo
{
private:
	int m_iId;
	string m_strName;
	bool m_bSex;
 
public:
	StudentInfo();
	~StudentInfo();
 
	int GetId();
	string GetName();
	bool GetSex();
 
	void SetId(int iId);
	void SetName(string strName);
	void SetSex(bool bSex);
};

 

II.发送方代码(客户端)

  初始化类对象并发送数据

 
//初始化stuInfo类对象
StudentInfo stuInfo;
stuInfo.SetId(111);
stuInfo.SetName("abcdefzzzzz");
stuInfo.SetSex(true);
send(m_clientSocket, (char*)&stuInfo, sizeof(StudentInfo), 0);

 

II.接收方代码(服务端)

  定义类对象并接收数据

 
StudentInfo stuInfo;
int iLenOfRecvData = -1;
//传输类对象数据
iLenOfRecvData = recv(clientSocket, (char*)&stuInfo, sizeof(StudentInfo), 0);
if (iLenOfRecvData > 0)		//如果接收的数据不为空
{
	cout << stuInfo.GetId() << endl;
	cout << stuInfo.GetName() << endl;
	cout << stuInfo.GetSex() << endl;
}

 

标签:发送,int,send,C++,char,传输,tcp,sizeof,结构
From: https://www.cnblogs.com/zhuchunlin/p/18219865

相关文章

  • c++ string 使用例子
      ===============一文读懂C++String类在算法竞赛中的常见用法string相较于C语言的字符数组可方便太多了,在算法竞赛中能大大节省我们的时间。以下是我在刷题中会使用到的常见String用法。注释都写好了。#include<iostream>#include<string>usingnamespacestd;int......
  • 电脑文件如何传输到手机上?
    1、当文件小时:通过微信即可实现2、当文件太大时:通过QQ传递;安卓手机:使用usb连接,电脑使用adb命令安装;苹果手机:爱思助手被投毒,当前不能使用。优先使用苹果官方提供的iTunes助手,可以到这里获取:https://pc.qq.com/如果iTunes功能上不能满足需求,可以使用另外一款第三方的软件3u......
  • 《计算机网络微课堂》5-9 TCP报文段的首部格式
    本节课我们介绍TCP报文段的首部格式。在之前的课程中我们曾介绍过,为了实现可靠传输,TCP采用了面向字节流的方式,如图所示TCP将应用进程交付下来的应用报文看作是字节流,存入TCP发送缓存中,但TCP在发送数据时是否发送缓存,取出一部分或全部字节,并给其添加一个首部使之成为TCP......
  • 《计算机网络微课堂》5-8 TCP的运输连接管理
    从本节课开始,我们将分两次课来介绍TCP的运输连接管理。5.8.1TCP的连接建立TCP是面向连接的协议,它基于运输连接来传送TCP报文段TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程TCP运输连接有以下三个阶段第一个阶段是建立TCP连接,也就是通过......
  • 《计算机网络微课堂》5-7 TCP 可靠传输的实现
    本节课我们介绍TCP可靠传输的实现。TCP基于以字节为单位的滑动窗口来实现可靠传输。我们来举例说明,这是因特网上的两台主机,他们之间已经建立了一个TCP连接,为了简单起见,我们假定数据传输只在一个方向进行,换句话说,发送方给接收方发送TCP数据报文段,接收方给发送方发送相应的......
  • 《计算机网络微课堂》5-6 TCP超时重传时间的选择
    本节课我们介绍TCP超时重传时间的选择,超时重传时间的选择是TCP最复杂的问题之一。我们来举例说明,假设主机A和B是因特网上的两台主机,他们之间已经建立了TCP连接,纵坐标为时间,现在主机A给主机B发送TCP数据报文段0,并记录下当前的时间。主机B收到后给主机A发送......
  • 《计算机网络微课堂》5-5 TCP的拥塞控制
    本节课我们介绍TCP的拥塞控制,首先来看拥塞控制的基本概念:在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做拥塞在计算机网络中的链路容量,交换节点中的缓存和处理机等都是网络的资源,若出现拥塞而不进行控制,整个网络的吞吐量......
  • 《计算机网络微课堂》5-4 TCP的流量控制
    本节课我们介绍TCP的流量控制:一般来说我们总是希望数据传输的更快一些但如果发送方把数据发送的过快,接收方就可能来不及接收,这就会造成数据的丢失所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收利用滑动窗口机制,可以很方便的在TCP连接上实现对发送方的......
  • 《计算机网络微课堂》5-3 UDP和TCP的对比
    本节课我们将从几个方面对比UDP和TCP。UDP和TCP是TCP/IP体系结构运输层中的两个重要协议,如图所示,这是我们之前课程中介绍过的TCP/IP体系结构,它的运输层有两个非常重要的协议UDP和TCP。在使用TCP/IP体系结构的网络通信中,这两个协议的使用频率仅次于往基层的IP协......
  • 文件跨境传输法律管控越来越严格,企业该如何有效应对?
    文件跨境传输已经成为非常普遍的业务需求,企业在世界各地的总分支处、合作伙伴,客户间开展业务时,必须基于数据的跨境流转而展开。但随着世界各国对数据安全的重视,文件跨境传输也日趋严格,各国在法律法规上均出具了更多的详细条例来规范和约束文件跨境传输行为,规避不合规的数据流转......