查看定义的sys/socket.h规范的通用套接字结构,它列出了:
sa_family_t sa_family address family
char sa_data[] socket address (variable-length data)
查看我的linux机器上位于/usr/includes/sys/socket.h的实际头文件,它定义如下。
struct osockaddr
{
unsigned short int sa_family;
unsigned char sa_data[14];
};
现在我知道如果我添加netinet/in.h它会定义sockaddr_in
结构,因为我使用AF_INET
它会使用它...
struct sockaddr_in {
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
但是,当我可以简单地使用通用osockaddr
结构时,我认为没有必要#include另一个lib(netinet / in.h)。
现在我了解我的osockaddr
成员sa_family
将与AF_INET
有关但我不清楚sa_data
成员内部究竟发生了什么...我假设{ {1}}与port,addr,zero
结构相关,但我不清楚。
问题:有人能举例说明使用通用sockaddr_in
结构的示例吗?
到目前为止我所拥有的......
osockaddr
答案 0 :(得分:0)
不要这样做。
你可以把sockaddr
想象成一种联盟:
struct sockaddr
{
short int sin_family;
union {
struct {
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
unsigned char sa_data[14]
};
};
所以,是的,如果你把sin_port
的两个字节用来表示正确的字节序,你可以将它们放在sa_data[0]
和sa_data[1]
中,然后你可以sin_addr
将4个字节放入sa_data[2]
到sa_data[6]
但是你真的不应该这样做,因为编程非常糟糕,它会使你的代码对其他任何人都不可读,包括6个月内你自己。
如果由于某些奇怪的原因你不想#include "netinet/in.h"
,你可以在你自己的代码文件中定义这个结构并使用它。
答案 1 :(得分:0)
netinet/in.h
不是额外的库,它只是您要以任何方式链接的一个库的定义子集。
这个通用地址就像一个抽象基类。你不应该创造它。如果您不关心您拥有的地址类型或是否要接受任何类型的地址,则只能使用它。
用法看起来像这样。
/* print any kind of socket address */
void prettyPrintAddress(struct sockaddr *addr) {
switch (addr->sa_family) {
case AF_INET:
// Typocast to the actual type
struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
// print [ipv4]:protocl:ipv4:port
break;
case AF_INET6:
// Typocast to the actual type
struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)addr;
// print [ipv6]:protocl:ipv6:port
break;
case AF_UNIX:
// Typocast to the actual type
struct sockaddr_un *un_addr = (struct sockaddr_un *)addr;
// print [unix]:socket-path
break;
...
}
}
prettyPrintAddress(anyAddress);
prettyPrintAddress((struct sockaddr *) in_addr);
prettyPrintAddress((struct sockaddr *) in6_addr);
prettyPrintAddress((struct sockaddr *) un_addr);