socket编程 sockaddr sockaddr_in

来源:互联网 发布:淘宝被投诉假冒品牌 编辑:程序博客网 时间:2024/06/07 06:15

socket编程 sockaddr sockaddr_in

Windows下与Linux下编写socket程序的区别
http://blog.chinaunix.net/uid-2270658-id-308160.html
sockaddr_in , sockaddr , in_addr区别Socket编程函数集(非常有用)
http://810364804.iteye.com/blog/2094531
ntohs, ntohl, htons,htonl的比较和详解
http://www.360doc.com/content/12/0222/10/54470_188560773.shtml

struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址。
在各种系统调用或者函数中,只要和网络地址打交道,就得用到这两个结构体。

include <netinet/in.h>//sockaddr是给操作系统使用struct sockaddr {    unsigned short    sa_family;     // 2 bytes address family, AF_xxx,sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族    char              sa_data[14];   // 14 bytes of protocol address};// IPv4 AF_INET sockets://程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口struct sockaddr_in {    short            sin_family;     // 2 bytes e.g. AF_INET, AF_INET6    //sockaddr用其余14个字节来表示sa_data, sockaddr_in把14个字节拆分成sin_port, sin_addr和sin_zero    unsigned short   sin_port;       // 2 bytes e.g. htons(3490), 端口号    struct in_addr   sin_addr;       // 4 bytes see struct in_addr, below, IP 地址    char             sin_zero[8];    // 8 bytes zero this if you want to, sin_zero用来填充字节使sockaddr_in和sockaddr保持一样大小};struct in_addr {    unsigned long s_addr;            // 4 bytes load with inet_pton()};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;

IP地址处理:
inet_addr(): –将IP地址从点数格式转换成无符号长整型,函数返回的地址已是网络字节格式, 如:
sockaddr_in ina;
ina.sin_addr.s_addr = inet_addr(“132.241.5.10”);//与调用函数htonl()功能一样,
//代码没有错误检查,当inet_addr()发生错误时返回-1。(无符号数)-1和IP地址255.255.255.255相符合!这是广播地址!所以要先进行错误检查
ina.sin_addr.s_addr = inet_addr(“192.168.0.1”); //是将一个点分制的IP地址(如192.168.0.1)转换为ina.sin_addr.s_addr结构中需要的32位IP地址(0xC0A80001)。
inet_ntoa():–将IP地址从长整型转换成点数格式, 如:
inet_ntoa(ina.sin_addr));
它将输出IP地址。需要注意的是inet_ntoa()将结构体in-addr作为一个参数,不是长整形。
同样需要注意的是它返回的是一个指向一个字符的指针。它是一个由inet_ntoa()控制的静态的固定的指针,所以每次调用 inet_ntoa(),它就将覆盖上次调用时所得的IP地址

BSD网络编程中包含了两个函数,用来在二进制地址格式和点分十进制字符串格式之间相互转换,这两个函数仅仅支持IPv4:
in_addr_t inet_addr(const char *cp);
//将网络地址转成二进制的数字
unsigned long int inet_addr(const char *cp); //将参数cp所指的网络地址字符串转换成网络所使用的二进制数字
//将网络地址转成二进制的数字
int inet_aton(const char* cp, struct in_addr *inp); //将参数cp所指的网络地址字符串转换成网络使用的二进制的数字,然后存于参数inp所指的in_addr结构中
//将二进制的数字转换成网络地址
char* inet_ntoa(struct in_addr in); //将参数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);如:char IPdotdec[20];  //存放点分十进制IP地址192.168.0.1struct in_addr s;   // IPv4地址结构体  inet_pton(AF_INET, IPdotdec, (void *)&s); // inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);

字节的网络顺序和主机顺序:
网络字节顺序与本地字节顺序之间的转换函数

htonl()--"Host to Network Long int"   32Bytes ntohl()--"Network to Host Long int"   32Bytes htons()--"Host to Network Short int"  16Bytes ntohs()--"Network to Host Short int"  16Bytes 

计算机数据表示存在两种字节顺序:
网络字节顺序NBO(Network Byte Order):
按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。
主机字节顺序(HBO,Host Byte Order):
不同的机器HBO不相同,与CPU设计有关,数据的顺序是由cpu决定的,而与操作系统无关, 如:
//将32位主机字符顺序转换成网络字符顺序
unsigned long int htonl(unsigned long int hostlong);//将参数指定的32位hostlong转换成网络字符顺序
//将16位主机字符顺序转换成网络字符顺序
unsigned short int htons(unsigned short int hostshort);//将参数指定的16位hostshort转换成网络字符顺序

一般的用法为:
程序员把类型、ip地址、端口填充sockaddr_in结构体,然后强制转换成sockaddr作为参数传递给系统调用函数

网络编程中一段典型的代码为:

int sockfd;struct sockaddr_in servaddr;sockfd = Socket(AF_INET, SOCK_STREAM, 0);// 填充struct sockaddr_in bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SERV_PORT);inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);// 强制转换成struct sockaddr connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
阅读全文
0 0
原创粉丝点击