具体来说,sin_addr似乎位于IPv4和IPv6套接字寻址的不同内存位置.这导致奇怪:
#include <stdio.h>
#include <netinet/in.h>
int main(int argc, char ** argv) {
struct sockaddr_in sa;
printf("sin_addr in sockaddr_in = %p\n", &sa.sin_addr);
printf("sin_addr in sockaddr_in6 = %p\n", &((struct sockaddr_in6*)&sa)->sin6_addr);
};
Run Code Online (Sandbox Code Playgroud)
输出:
sin_addr in sockaddr_in = 0x7fffa26102b4
sin_addr in sockaddr_in6 = 0x7fffa26102b8
Run Code Online (Sandbox Code Playgroud)
为什么这两个值不一样?
由于这指向相同的数据(要连接的地址),因此应该位于相同的地址.否则,你应该如何用sockaddr_in调用inet_ntop,你不知道是IPv4还是IPv6?
在C中如果你有一个特定类型的数据包,你通常做的是定义一些结构并将char*转换为指向结构的指针.在此之后,您可以直接以编程方式访问网络数据包中的所有数据字段.像这样:
struct rdp_header {
int version;
char serverId[20];
};
Run Code Online (Sandbox Code Playgroud)
获得网络数据包后,您可以快速执行以下操作:
char * packet;
// receive packet
rdp_header * pckt = (rdp_header * packet);
printf("Servername : %20.20s\n", pckt.serverId);
Run Code Online (Sandbox Code Playgroud)
这种技术对基于UDP的协议非常有用,并且允许使用非常少的代码进行非常快速和非常有效的数据包解析和发送,以及简单的错误处理(只需检查数据包的长度).在java中有同样的,同样快速的方法吗?或者你被迫使用基于流的技术?