第一步:The WSAStartup function initiates use of WS2_32.DLL by a process. 在所有 Windows Sockets 函数中,只有启动函数 WSAStartup() 和终止函数 WSACleanup() 是必须使用的。
启动函数必须是第一个使用的函数,而且它允许指定 Windows Sockets API 的版本,并获得 SOCKETS的特定的一些技术细节。本结构如下:
int PASCAL FAR WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); 其中 wVersionRequested 保证 SOCKETS 可正常运行的 DLL 版本,如果不支持,则返回错误信息。 我们看一下下面这段代码,看一下如何进行 WSAStartup() 的调用
WORD wVersionRequested;// 定义版本信息变量 WSADATA wsaData;//定义数据信息变量 int err;//定义错误号变量 wVersionRequested = MAKEWORD(1,1);//给版本信息赋值 err = WSAStartup(wVersionRequested, &wsaData);//给错误信息赋值 if(err!=0) { return;//告诉用户找不到合适的版本 } //确认 Windows Sockets DLL 支持 1.1 版本 //DLL 版本可以高于 1.1 //系统返回的版本号始终是最低要求的 1.1,即应用程序与DLL 中可支持的最低版本号 if(LOBYTE(wsaData.wVersion)!= 1|| HIBYTE(wsaData.wVersion)!=1) { WSACleanup();//告诉用户找不到合适的版本 return; } //Windows Sockets DLL 被进程接受,可以进入下一步操作 关闭函数使用时,任何打开并已连接的 SOCK_STREAM 套接字被复位,但那些已由 closesocket() 函数关闭的但仍有未发送数据的套接字不受影响,未发送的数据仍将被发送。程序运行时可能会多次调用 WSAStartuo() 函数,但必须保证每次调用时的 wVersionRequested 的值是相同的。 第二步:在初始化了WSAStartup后建立Socket MSDN:The socket function creates a socket that is bound to a specific service provider. 初始化WinSock的动态连接库后,需要在服务器端建立一个监听的Socket,为此可以调用Socket()函数用来建立这个监听的Socket,并定义此Socket所使用的通信协议。此函数调用成功返回Socket对象,失败则返回INVALID_SOCKET(调用WSAGetLastError()可得知原因,所有WinSocket 的函数都可以使用这个函数来获取失败的原因)。
SOCKET PASCAL FAR socket( int af, int type, int protocol ) 参数: af:目前只提供 PF_INET(AF_INET); type:Socket 的类型 (SOCK_STREAM、SOCK_DGRAM); protocol:通讯协定(如果使用者不指定则设为0); 如果要建立的是遵从TCP/IP协议的socket,第二个参数type应为SOCK_STREAM,如为UDP(数据报)的socket,应为SOCK_DGRAM。 第三步:绑定(服务器端需要) MSDN:The bind function associates a local address with a socket. 为服务器端定义的这个监听的Socket指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。 int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR *name,int namelen );
参 数: s:Socket对象名; name:Socket的地址值,这个地址必须是执行这个程式所在机器的IP地址; namelen:name的长度; 如果使用者不在意地址或端口的值,那么可以设定地址为INADDR_ANY,及Port为0,Windows Sockets 会自动将其设定适当之地址及Port (1024 到 5000之间的值)。此后可以调用getsockname()函数来获知其被设定的值。 上面那个socketaddr是这样定义的:The sockaddr structure varies depending on the protocol selected. Except for the sin*_family parameter, sockaddr contents are expressed in network byte order. 这个结构经常被 struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}; 所代替 in_addr是一个联合体 定义如下 typedef 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; } in_addr;

|