您的位置:首页 > 其它

struct sockaddr 与 struct sockaddr_in

2013-05-16 09:39 477 查看

struct sockaddr 与 struct sockaddr_in

2009-12-13 14:05:50

struct sockaddr {

unsigned short sa_family; /* address family, AF_xxx */

char sa_data[14]; /* 14 bytes of protocol address */

};

sa_family是地址家族,一般都是“AF_xxx”的形式。好像通常大多用的是都是AF_INET。

sa_data是14字节协议地址。

此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。

但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构

sockaddr_in(在netinet/in.h中定义):

struct sockaddr_in {

short int sin_family; /* Address family */

unsigned short int sin_port; /* Port number */

struct in_addr sin_addr; /* Internet address */

unsigned char sin_zero[8]; /* Same size as struct sockaddr */

};

struct in_addr {

unsigned long s_addr;

};

typedef struct in_addr {

union {

struct{

unsigned char s_b1,

s_b2,

s_b3,

s_b4;

} S_un_b;

struct {

unsigned short s_w1,

s_w2;

} S_un_w;

unsigned long S_addr;

} S_un;

} IN_ADDR;

sin_family指代协议族,在socket编程中只能是AF_INET

sin_port存储端口号(使用网络字节顺序)

sin_addr存储IP地址,使用in_addr这个数据结构

sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。

s_addr按照网络字节顺序存储IP地址

sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向

sockadd的结构体,并代替它。也就是说,你可以使用sockaddr_in建立你所需要的信息,

在最后用进行类型转换就可以了bzero((char*)&mysock,sizeof(mysock));//初始化

mysock结构体名

mysock.sa_family=AF_INET;

mysock.sin_addr.s_addr=inet_addr("192.168.0.1");

……

等到要做转换的时候用:

(struct sockaddr*)mysock

sa_data的含义是由sa_family决定

如果sa_family=AF_INET

则sa_data就是sockaddr_in的sin_addr和sin_port

换句话说,这时sockaddr可以当作sockaddr_in看

Sockfd是调用socket函数返回的socket描述符,my_addr是个指向包含有本机IP地址及端口号等信息的sockaddr类型的指

针;addrlen常被设置为sizeof(struct sockaddr)。

  

structsockaddr结构类型是用来保存socket信息的:   

struct sockaddr {   

unsigned short sa_family; /* 地址族, AF_xxx */

char sa_data[14]; /* 14 字节的协议地址 */

};

   sa_family一般为AF_INET,代表Internet(TCP/IP)地址族;

sa_data则包含该socket的IP地址和端口号。

  

另外更有一种结构类型:   

struct sockaddr_in {   

short int sin_family; /* 地址族 */

   unsigned short int sin_port; /* 端口号 */   

struct in_addr sin_addr;/* IP地址 */   

unsigned char sin_zero[8]; /* 填充0 以保持和struct sockaddr同样大小*/   

};   这个结构更方便使用。sin_zero用来将sockaddr_in结构填充到和struct

sockaddr同样的长度,能用bzero()或memset()函数将其置为零。指向sockaddr_in的指针和指向sockaddr的指针能相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你能在函数调用的时候将一个指向

sockaddr_in的指针转换为指向sockaddr的指针;或相反。

BSD网络软件中包含了两个函数,用来在二进制地址格式和点分十进制字符串格式之间相互转换,但是这两个函数仅仅支持IPv4。

in_addr_t inet_addr(const char *cp);

char *inet_ntoa(struct in_addr in);

功能相似的两个函数同时支持IPv4和IPv6

const char *inet_ntop(int domain, const void *addr, char *str, socklen_t size);

int inet_pton(int domain, const char *str, void *addr);

通常的用法是:

int sockfd;

struct sockaddr_in my_addr;

sockfd = socket(AF_INET, SOCK_STREAM, 0);

my_addr.sin_family = AF_INET; /* 主机字节序 */

my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */

my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");

bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */

//memset(&my_addr.sin_zero, 0, 8);

/* 为bind()做错误检查: */

if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)

{

return NULL;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: