Socket传输结构体数据注意事项

简介: 【1 背景】在Socket通信中,要传输结构化的数据或者要进行协议数据传输的时候,发送端必须要构造结构体进行数据传输。接收端也必须通过同样的结构体进行解析。但Socket传输结构体数据时候,稍有不慎就会出现:1)解析数据出错;2)接收数据不完整;3)解析为乱码等的Bug。

【2 举例】

如下是接收端解析数据为乱码甚至崩溃的一类常见错误。


结构体也就是一段连续的内存。  但是类似如下的结构体:

typedef struct _PER_SPIDER_INFO

{

UINT nTimeDelay;

UINT nRtnCode;

UINT nUrlPageLen;

char* pszUrlPage;

}PER_SPIDER_INFO;


不能直接通过传输的。

【3 根本原因】

如下:

1)结构体成员pszUrlPage是指针,指向的是结构体以外的内存地址,也就是在结构体PER_SPIDER_INFO外的非连续的地址空间。

2)如果仅传输pszUrlPage,也就是传输了一个地址,在当前进程空间是可以索引到对应的值。但是一旦通过Socket实现网络传输,即出现了跨进程、跨网络的传输,一个地址传输过去,极大可能甚至100%会读到我们不想要的地址空间,读取的值也会出错。一旦该地址空间不允许读,则会导致程序崩溃。(如下图所示)

3)可以传输,正如2)所说,但一旦接受后对方机器无法正确解析,甚至程序崩溃。image.png

【4 Bug解决步骤路演】

Step1: 缩小范围,只传输int数据,ok;但单包含了字符串指针就不可以;基本锁定是字符串这里除了问题。

Step2:字符串指针换成字符串数组,Bug不再出现。说明至少是连续内存这里出了问题。期间 ,怀疑动态分配内存malloc()以及strcpy,memcpy,传输结构体数据的长度出了问题,花了近3个小时排查 。

Step3:进而换成给定长度(大小结合项目定)的字符串数组,Bug解决掉。


【5 修正后】

typedef struct _PER_SPIDER_INFO

{

UINT nTimeDelay;

UINT nRtnCode;

UINT nUrlPageLen;

char szUrlPage[MAX_URL_PATH]

}PER_SPIDER_INFO;

就可以通过socket传输了。


【6反思与思考】

但是不是包含指针的就不能传输了呢?不是的,只要内存处理的得当也是可以的。回头有示例再附上解析。

未完待续。


image.png

相关文章
|
2月前
|
存储 Python
Python网络编程基础(Socket编程) UDP 发送和接收数据
【4月更文挑战第10天】对于UDP客户端而言,发送数据是一个相对简单的过程。首先,你需要构建一个要发送的数据报,这通常是一个字节串(bytes)。然后,你可以调用socket对象的`sendto`方法,将数据报发送到指定的服务器地址和端口。
|
2月前
|
网络协议 Python
python中socket客户端发送和接收数据
【4月更文挑战第7天】本教程聚焦TCP客户端数据发送与接收。使用Python的`socket`模块,通过`send()`发送字节串至服务器,如`client_socket.send(message_bytes)`;用`recv()`接收数据,如`received_data = client_socket.recv(buffer_size)`。异常处理确保网络错误时程序健壮性,例如`try-except`捕获`socket.error`。理解和掌握这些基础操作对于构建稳定的TCP客户端至关重要。
|
2月前
|
监控 网络协议 安全
socket开发遇到的问题及注意事项实战
socket开发遇到的问题及注意事项实战
35 1
|
19天前
|
网络协议
逆向学习网络篇:通过Socket建立连接并传输数据
逆向学习网络篇:通过Socket建立连接并传输数据
14 0
|
1月前
|
监控 网络协议 Java
Java Socket编程 - 基于TCP方式的二进制文件传输
Java Socket编程 - 基于TCP方式的二进制文件传输
24 0
|
2月前
|
网络协议 Java 网络安全
【计算机网络】—— Socket通信编程与传输协议分析
【计算机网络】—— Socket通信编程与传输协议分析
83 0
|
2月前
|
存储 Python
Python网络编程基础(Socket编程)接收和发送数据
【4月更文挑战第9天】在UDP服务器编程中,我们已经创建了一个UDP套接字并绑定了地址和端口。接下来,服务器需要能够接收来自客户端的数据,并能够对这些数据进行处理和响应。下面,我们将详细讲解如何在UDP服务器中接收和发送数据。
|
22天前
|
缓存 监控 Java
Java Socket编程最佳实践:优化客户端-服务器通信性能
【6月更文挑战第21天】Java Socket编程优化涉及识别性能瓶颈,如网络延迟和CPU计算。使用非阻塞I/O(NIO)和多路复用技术提升并发处理能力,减少线程上下文切换。缓存利用可减少I/O操作,异步I/O(AIO)进一步提高效率。持续监控系统性能是关键。通过实践这些策略,开发者能构建高效稳定的通信系统。
|
22天前
|
IDE Java 开发工具
从零开始学Java Socket编程:客户端与服务器通信实战
【6月更文挑战第21天】Java Socket编程教程带你从零开始构建简单的客户端-服务器通信。安装JDK后,在命令行分别运行`SimpleServer`和`SimpleClient`。服务器监听端口,接收并回显客户端消息;客户端连接服务器,发送“Hello, Server!”并显示服务器响应。这是网络通信基础,为更复杂的网络应用打下基础。开始你的Socket编程之旅吧!
|
22天前
|
Java
Java Socket编程与多线程:提升客户端-服务器通信的并发性能
【6月更文挑战第21天】Java网络编程中,Socket结合多线程提升并发性能,服务器对每个客户端连接启动新线程处理,如示例所示,实现每个客户端的独立操作。多线程利用多核处理器能力,避免串行等待,提升响应速度。防止死锁需减少共享资源,统一锁定顺序,使用超时和重试策略。使用synchronized、ReentrantLock等维持数据一致性。多线程带来性能提升的同时,也伴随复杂性和挑战。