假设我想将以下数据发送到使用C或C++的套接字,所有这些都在一个数据包中:
Headers
-------
Field 1: 2 byte hex
Field 2: 2 byte hex
Field 3: 4 byte hex
Data
----
Field1 : 2 byte hex
Field1 : 8 byte hex
Run Code Online (Sandbox Code Playgroud)
代码通常看起来像创建和发送包含所有这些数据的数据包?
Rob*_*obᵩ 19
假设您的程序已经被组织为将标题放在一个中struct,将数据放在另一个中struct.例如,您可能拥有以下数据结构:
#include <stdint.h>
struct header {
uint16_t f1;
uint16_t f2;
uint32_t f3;
};
struct data {
uint16_t pf1;
uint64_t pf2;
};
Run Code Online (Sandbox Code Playgroud)
我们称这个组织为"主机格式".对我来说,主机格式是什么并不重要,只要它对你的程序的其余部分有用.让我们调用您将传递给send()"网络格式"调用的格式.(我选择这些名称来匹配htons(host-to-network-short)和htonl(host-to-network-long)名称.)
以下是我们可能会发现的一些转换函数.其中每个都将主机格式结构转换为网络格式缓冲区.
#include <arpa/inet.h>
#include <string.h>
void htonHeader(struct header h, char buffer[8]) {
uint16_t u16;
uint32_t u32;
u16 = htons(h.f1);
memcpy(buffer+0, &u16, 2);
u16 = htons(h.f2);
memcpy(buffer+2, &u16, 2);
u32 = htonl(h.f3);
memcpy(buffer+4, &u32, 4);
}
void htonData(struct data d, char buffer[10]) {
uint16_t u16;
uint32_t u32;
u16 = htons(d.pf1);
memcpy(buffer+0, &u16, 2);
u32 = htonl(d.pf2>>32);
memcpy(buffer+2, &u32, 4);
u32 = htonl(d.pf2);
memcpy(buffer+6, u32, 4);
}
void htonHeaderData(struct header h, struct data d, char buffer[18]) {
htonHeader(h, buffer+0);
htonData(d, buffer+8);
}
Run Code Online (Sandbox Code Playgroud)
要发送数据,请执行以下操作:
...
char buffer[18];
htonHeaderData(myPacketHeader, myPacketData, buffer);
send(sockfd, buffer, 18, 0);
...
Run Code Online (Sandbox Code Playgroud)
同样,您不必使用我定义的header和data结构.只需使用您的程序需要.关键是你有一个转换函数,它将定义良好的偏移量的所有数据以明确定义的字节顺序写入缓冲区,并将该缓冲区传递给send()函数.
在网络连接的另一端,您将需要一个程序来解释它接收的数据.在这一方面,您需要编写相应的函数(ntohHeader等).这些函数将memcpy位从缓冲区转移到局部变量,它可以传递给ntohs或ntohl.我会把这些功能留给你写.
好吧,通常看起来它正在准备将数据包结构放入内存缓冲区(使得明智的调用成为htonl函数族).
如果然后将使用send,sendto,sendmsg或write功能,希望有很多的照顾与缓冲器和良好的错误处理/报告的长度所取.
(或者发送的Win32 api之一,如果这是目标平台.)
你会在Beej的网络编程指南中找到关于这一切的很好的演示.
特别是对于字节打包部分(使用endian考虑),请查看序列化主题.(该部分的详细信息比纯固定大小的整数数据类型需要的更多.
| 归档时间: |
|
| 查看次数: |
47706 次 |
| 最近记录: |