2015-09-23 37 views
-1

纵观通用插座结构定义sys/socket.h规范它列出:Socket编程(SYS/socket.h中)

sa_family_t sa_family  address family 
char   sa_data[]  socket address (variable-length data) 

纵观位于/usr/includes/sys/socket.h我实际的头文件我的linux机器,它定义如下。

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部件的内部去...我假设port,addr,zero相对于sockaddr_in结构,但我不清楚。

问题:任何人都可以给我一个使用通用osockaddr结构的例子吗?

我有什么到目前为止....

#include<sys/socket.h>  
int main(void){ 
    struct osockaddr address; 
    address.sa_family = AF_INET; 
    address.sa_data = ? //What goes here (port, addr, zero)? 
    return 0; 
} 

回答

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); 
+0

我会初始化并链接整个'netinet/in.h'文件,所以它是额外的......我不需要链接它,'sys/socket.h'定义了socket(),bind (),listen(),rec(),send()并且在没有它的情况下工作得很好...... –

+0

不,没有任何东西与头文件链接。这不是Java或您从哪里来的任何语言。两个标题都属于同一个标准库。 'netinite/in.h'只是告诉你这个库有一些功能。不包括它并不意味着这些功能不包括在内。你甚至可以使用这些功能而不包括它。 – x539

+0

一切都是链接的....如果我不包含'#include '头文件,我将无法使用该文件中定义的任何“特性”... #include是编译器的预处理器指令...如果我不包含该文件,我不会初始化它内部的任何内容,从而使我的程序更高效...... –

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"你可以在你自己的代码文件中定义这个结构并使用它。

+0

为什么使用标准的'sys/socket.h'库结构是如此“奇怪”?是不是为了这个确切的目的而设计的?如果这种编程很糟糕,为什么它是一个标准(并且被ISO认可)?如果lib是用于套接字sys/socket.h并且定义了它自己的结构......为什么使用它的编程不好呢?包括并初始化另一个库来修补声音,如错误的编程...... –

+1

'socket.h'旨在支持任何类型的套接字。你需要一个IP套接字,所以你需要在'netinet/in.h'(套接字库的一个组成部分)的IP套接字中使用标准的结构。 'socket.h'不包含所有类型套接字的所有结构,因为它们有很多,你也可以定义自己的套接字。 'sockaddr'并不意味着它自己实例化,它只是一个占位符,它是C++抽象基类的C等值。 – shoosh

+0

是的,通用套接字结构体'osockaddr'可以支持任何类型的结构体,所以我只是想用'AF_INET'系列...你的回答几乎超出了我的定义,使用两个字节的端口,4字节addr在'sa_data'知道我有一个IPv4地址并且知道我要将它绑定到哪个端口,我可以相应地更改sa_data [14]的长度。是的,我知道这不是“便携式”解决方案,因为可能有IPv6地址会改变长度......但我知道它是IPv4。 –