socket的初始化与IP地址的转换

来源:互联网 发布:赌球软件哪个好 编辑:程序博客网 时间:2024/06/05 11:54

socket是介于传输层和应用层之间的一个API,它比一般的网络前端更靠近底层,它可以直接基于TCP/UDP协议甚至网络层的IP协议进行编程。

WSAStartup()用于初始化windowssockets,返回WSADATA结构体,只有调用了WSAStartup()以后,才能继续调用windowssockets的其它API。需要包含头文件:

#include "stdafx.h"#include <stdio.h>#include <winsock2.h>#include <stdlib.h>#pragma comment (lib,"ws2_32.lib")

Int WSAStartup(WORD version, WSAData* pWSAData),返回值是一个状态码,等于0则表示创建成功。第一个参数是输入,用于指定winsock的版本,它是一个字,包含两个字节,高字节用于存储副版本号,低字节用于存储主版本号,一般用makeword()进行输入。第二个参数是一个输出,返回了一个指向生成的WSADATA的指针,WSADATA结构体里面的具体内容:

typedef struct WSAData {        WORD                    wVersion;        WORD                    wHighVersion;#ifdef _WIN64        unsigned short          iMaxSockets;        unsigned short          iMaxUdpDg;        char FAR *              lpVendorInfo;        char                    szDescription[WSADESCRIPTION_LEN+1];        char                    szSystemStatus[WSASYS_STATUS_LEN+1];#else        char                    szDescription[WSADESCRIPTION_LEN+1];        char                    szSystemStatus[WSASYS_STATUS_LEN+1];        unsigned short          iMaxSockets;        unsigned short          iMaxUdpDg;        char FAR *              lpVendorInfo;#endif} WSADATA;

wVersion

WindowsSockets DLL期望调用者使用的Windows Sockets规范的版本。 高位字节存储副版本号, 低位字节存储主版本号,可以用WORDMAKEWORD(BYTE,BYTE ) 返回这个值,例如:MAKEWORD(1,1)

wHighVersion

这个DLL能够支持的WindowsSockets规范的最高版本。通常它与wVersion相同。

szDescription

以null结尾的ASCII字符串,WindowsSockets DLL将对WindowsSockets实现的描述拷贝到这个字符串中,包括制造商标识。文本(最多可以有256个字符)可以包含任何字符,但是要注意不能包含控制字符和格式字符,应用程序对其最可能的使用方式是把它(可能被截断)显示在在状态信息中。

szSystemStatus

以null结尾的ASCII字符串,WindowsSockets DLL把有关的状态或配置信息拷贝到该字符串中。Windows SocketsDLL应当仅在这些信息对用户或支持人员有用时才使用它们,它不应被作为szDescription域的扩展。

iMaxSockets

单个进程能够打开的socket的最大数目。WindowsSockets的实现能提供一个全局的socket池,可以为任何进程分配;或者它也可以为socket分配属于进程的资源。这个数字能够很好地反映WindowsSockets DLL或网络软件的配置方式。应用程序的编写者可以通过这个数字来粗略地指明Windows Sockets的实现方式对应用程序是否有用。例如,XWindows服务器在第一次启动的时候可能会检查iMaxSockets的值:如果这个值小于8,应用程序将显示一条错误信息,指示用户重新配置网络软件(这是一种可能要使用szSystemStatus文本的场合)。显然无法保证某个应用程序能够真正分配iMaxSockets个socket,因为可能有其它WindowsSockets应用程序正在使用。

iMaxUdpDg

WindowsSockets应用程序能够发送或接收的最大的用户数据包协议(UDP)的数据包大小,以字节为单位。如果实现方式没有限制,那么iMaxUdpDg为零。在Berkeleysockets的许多实现中,对于UDP数据包有个固有的限制(在必要时被分解),大小为8192字节。WindowsSockets的实现可以对碎片重组缓冲区的分配作出限制。对于适合的WindowsSockets实现,iMaxUdpDg的最小值为512。注意不管iMaxUdpDg的值是什么,都不推荐你发回一个比网络的最大传送单元(MTU)还大的广播数据包。(WindowsSockets API 没有提供发现MTU的机制,但是它不会小于512个字节)。WinSock2.0版中已被废弃。

lpVendorInfo

指向销售商的数据结构的指针。这个结构的定义(如果有)超出了WindowsSockets规范的范围。WinSock2.0版中已被废弃。


IP地址的转换

在计算机网络这门课中,我们使用的是点分法进行IP地址的表示,但在windows socket编程中,要使用网络字节顺序地址或者主机字节顺序地址。

socket中,ip地址使用结构体in_addr表示,里面是一个联合体(union),联合体里有很多种IP地址的表示方式,但最简单常见的就是u_long S_addr表示。

网络字节顺序地址和点分地址的高低字节是反着的,例如1.128.0.000000001.10000000.0.0)用网络字节地址就是2^15+2^0=32769。主机字节顺序地址则会根据主机的变化而变化。在X86的机器上,主机字节顺序地址与网络字节顺序地址的字节又是反着的,所以就等于将点分地址转化为十进制。

点分十进制地址一般采用字符串char[]进行存储,网络字节地址和主机字节地址采用unsigned long来存储,采用u_longinet_addr(const char* )将点分地址转换为网络字节顺序地址,char* inet_ntoa(struct in_addr in)将网络字节顺序地址转换为点分地址。

主机字节顺序格式与网络字节顺序格式之间也有函数进行转换。Htonl,ntohl等函数就是。

例如如下一段程序

#include "stdafx.h"#include <stdio.h>#include <winsock2.h>#include <stdlib.h>#pragma comment (lib,"ws2_32.lib")int main(){const char s[20]="1.128.0.0";char* s2;WSADATA wsaData;in_addr nipa,hipa;//net ip address, host ip addressif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("failed\n");return 0;}nipa.S_un.S_addr = inet_addr(s);printf("netip: %d\n", nipa.S_un.S_addr);s2 = inet_ntoa(nipa);printf("point-decimal: %s\n", s2);hipa.S_un.S_addr = ntohl(nipa.S_un.S_addr);printf("hostip: %d\n", hipa.S_un.S_addr);printf("version: %d.%d\n",LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));printf("%s\n", wsaData.szDescription);printf("%d\n", sizeof(wsaData));WSACleanup();    return 0;}

执行结果如下:

0 0
原创粉丝点击