Winsock编程入门--2.寻址协议(IPv4)

    Winsock是与协议无关的接口,这里我们主要介绍广泛使用的IP协议,其版本为当前的IPv4(IPv6暂不介绍).

IPv4寻址

    IPv4中,计算机的地址用32位的二进制表示,称为IP地址.当客户机使用TCP或UDP与服务器通讯时,必须指定其IP地址及通讯端口.服务器想要侦听客户机请求时,也要指定IP地址与端口.Winsock中使用SOCKADDR_IN结构来设置这些信息:

struct sockaddr_in
{
short           sin_family;
u_short         sin_port;
struct in_addr  sin_addr;
char            sin_zero[8];
};

    sin_family必须为AF_INET,设定Winsock使用IP地址族.

    sin_port定义TCP或UDP的通讯端口. 端口要认真选择,一些知名服务使占用了特定的端口,如FTP及HTTP

    sin_addr记录了IPv4的4字节地址,它是无符号长整型,IP地址通常以"a.b.c.d"表示,每个字母表示一个数字与IP地址的每个字节对应(从左到右)
    
    sin_zero只是用来占用字节空间使得SOCKADDR_IN结构与SOCKADDR结构一样.

   函数 inet_addr可以将字符串"a.b.c.d"格式的IP地址转换为32位无符号长整型的IP地址.
    
    unsigned long inet_addr(const char FAR *cp); 

    cp就是指向null结尾的字符串形式IP地址.返回以网络字符顺序表示的IP地址.

字节顺序
    
    不同计算机的处理器以big-endian或little-endian形式来表示数字.而IP地址与端口需要多个字节来表示,它们在不同计算机上的表示顺序称为主机字节顺序.而IP地址与端口在网络中的表示不应该有差异,必须以big-endian形式表示,称为网络字节顺序.

    下面的Winsock API可以将主机字节顺序转换为网络字节顺序:

    u_long htonl(u_long hostlong);
    
    int WSAHtonl(SOCKET s, u_long hostlong, u_long FAR * lpnetlong);

    u_short htons(u_short hostshort);

    int WSAHtons( SOCKET s, u_short hostshort, u_short FAR * lpnetshort);

    而下而的API则将网络字节顺序转换为主机字节顺序:

    u_long ntohl(u_long netlong);

    int WSANtohl(SOCKET s,u_long netlong, u_long FAR * lphostlong);

    u_short ntohs(u_short netshort);

    int WSANtohs(SOCKET s, u_short netshort, u_short FAR * lphostshort);

    下面代码说明了如何用SOCKADDR_IN结构来设置地址与端口:

     SOCKADDR_IN InternetAddr;
     INT nPortId = 5150;
     InternetAddr.sin_family = AF_INET;
    //将字符串表示的IP地址转换为4个字节表示的整数,并赋值给sin_addr
     InternetAddr.sin_addr.s_addr = inet_addr("136.149.3.29");
    //nPortId变量以主机字节的顺序存储.将nPortId转换为网络字节顺序,并赋值给sin_port
     InternetAddr.sin_port = htons(nPortId);

 IP地址不是那么容易记忆,可以使用更友好的主机名来代替IP地址,比如www.somewebsite.com,用FTP来表示文件传输协议端口号21.与之相关的函数有:getaddrinfo, getnameinfo, gethostbyaddr, gethostbyname, gethostname, getprotobyname, getprotobynumber, get-servbyname, 及getservbyport. 这些函数的异步版本有: WSAAsyncGetHostByAddr, WSAAsyncGetHostByName, WSAAsyncGetProtoByName, WSAAsyncGetProtoByNumber, WSAAsyncGetServBy- Name,及WSAAsyncGetServByPort.

posted @ 2006-06-05 16:05  Max Woods  阅读(1594)  评论(0编辑  收藏  举报