WinSock的网络地址表示--WinSock编程

2015/05/07 计算机网络

在IP网络环境下,对于一个通信进程来说,必须明确三方面的信息,一是进程所在的主机IP地址,二是通信所采用的协议,三是所使用的协议端口号。IP地址可以区分网络中不同的主机,协议则指明通信所用的传输层协议是TCP还是UDP,而端口号则可以用于区分同一个主机中正在运行的采用同一传输层协议进行通信的不同进程。通过这三方面的信息可以唯一确定在网络中参与通信的一个进程,因此进程的网络地址可以使用三元组(协议,IP地址,端口号)来标识

地址结构

1.in_addr结构:用于存储一个IPv4地址。

struct in_addr{
	union{
		struct{u_char s_b1,s_b2,s_b3,s_b4}S_un_b;
		struct{u_short s_w1,s_w2}S_un_w;
		U_long S_addr;
	}S_un;
}

该结构体只用一个共用体(union)类型的字段S_un,专门用来存储32位的IP地址,共用体三个成员分别是:

a.由4个单字节字段组成的结构体变量S_un_b,使用该成员便于分别处理IP地址的4个字节;

b.由2个双字节字段组成的结构体变量S_un_w,使用该成员可将IP地址的高16位和低16位分别作为无符号短整数处理。

c.无符号长整型变量S_add,使用该成员可将IP地址作为一个无符号长整数处理。

将IP地址“192.168.1.1”赋值到in_addr型变量add中:

struct in_addr add;
add.S_un_S_un_b.s_b1=192;
add.S_un_S_un_b.s_b2=168;
add.S_un_S_un_b.s_b3=1;
add.S_un_S_un_b.s_b4=1;

2.sockaddr_in 结构:用于存储IP地址,传输协议端口号等信息,该结构体IP地址和协议端口号进行封装。

结构体定义:

struct sockaddr_in{
	short sin_family;           //地址族 IP协议地址对应的值为AF_INET
	u_short sin_port;           //16为端口号,需使用网络字节顺序
	struct in_addr sin_addr;    //32位IP地址,需使用网络字节顺序
	char sin_zero[8];           //保留不用
}  

3.sockaddr结构体:通用的套接字结构体,是为了兼容多个不同协议族的地址而设计的。

struct sockaddr{
	u_short sa_family;          //协议地址族
	char sa_data[14];           //协议地址
}

当程序使用TCP/IP协议时,sockaddr结构体的第一个域sa_family应填写AF_INET,表示是IP协议族地址,第二个域的前2个字节是端口号,随后4个字节是IP地址,剩余的8个字节不用。可以发现与sockaddr_in结构体存储的内容完全一致。首先定义一个sockaddr_in类型的指针变量p,通过强制类型转换,让p指向sockaddr结构类型的变量,然后通过指针p可按sockaddr_in类型的各个字段完成赋值。示例代码如下:

struct sockaddr a;
struct sockaddr_in *p;
p=(sockaddr_in*)&a;
p->sin_family=AF_INET;
p->sin_port=54321;
p->sin_addr=inet_addr("192.168.1.1");
地址转换函数

点分十进制表示的IP地址是一种便于人们书写和记忆的一种格式,但它并不是计算机内部的IP地址表示方式,计算机内部的IP地址是以无符号长整数方式存储的,因此在程序中,输入输出IP地址时,通常是使用点分十进制表示的IP地址,而程序内部则使用无符号长整型的IP地址,这就导致程序中经常要进行IP地址不同形式间的转换,为了编程方便,WinSock提供了一组地址转换函数。

1.inet_addr函数

原型:unsigned long inet_addr(const char * cp);

功能:将参数cp指向的点分十进制字符串表示的IP地址转换为32位的无符号长整型数。

2.inet_aton函数

原型:int inet_aton(const char *cp,struct in_addr *inp);

功能:将参数cp指向的点分十进制字符串表示的IP地址转换为32位的无符号长整型数,并存放于参数inp指向的in_addr结构体变量中。

3.inet_ntoa函数

原型:char *inet_ntoa(struct in_addr in);

功能:将一个包含在in_addr结构体变量in中的长整型IP地址转换为点分十进制形式。

WinSock错误处理

WinSock函数在执行结束时都会返回一个值,如果函数执行不成功,绝大多数函数会返回SOCKET_ERROR,虽然通过返回值就可以知道函数调用成不成功,但是无法判断函数执行不成功的原因,因此WinSock提供WSAGetLastError()函数可解决该问题,使用WSAGetLastError()函数可以获取上一次WinSock函数调用时的错误代码。

函数原型:int WSAGetLastError(void);

该函数的返回值是一个整数,它是上一次调用WinSock函数出错时错误对应的错误代码,由于引起WinSock函数调用出错的原因很多,为了便于编写出界面友好的应用程序和方便编程者调试程序,WinSock规范列举出所有的出错原因并给每一种原因定义了一个整数类型(int)的编号,该编号称作为错误码。然后根据错误码来查找是哪一种错误。

Search

    Post Directory