用简单的代码和演示说明了WinSocket的使用一般必要步骤。
先看看程序执行的效果吧:
最上面的一个窗口为服务端,下面的窗口为客户端,服务端的主循环负责接收数据。如果客户端输出“exit”字符串的话,则服务端和客户端程序终止。这个示例主要是通过简单的代码让初学者了解到WSA(WinSocketAPI)的启动相关的函数和参数,以及收发相关的两个函数的使用,最后释放WS资源。可以理解为一个最小的C/S演示。
以下为两个程序的源代码,在VS2005下编译通过。
服务端:
//ServerMain.cpp #include <stdio.h> #include <WinSock2.h>//winsocket2 的头文件 #include <iostream> #pragma comment(lib, "WS2_32.lib")//winsocket2需要的库文件 using namespace std; int main() { //第一步:初始化网络 WSADATA wsaData; WORD wVersion = MAKEWORD(2,2); WSAStartup(wVersion, &wsaData); //第二步:建立一个socket SOCKET sServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //第三步:填充sockaddr_in结构 sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(16568); sin.sin_addr.S_un.S_addr = INADDR_ANY; //第四步:绑定这个套接字到一个本地地址 if ( ::bind( sServer, (LPSOCKADDR)&sin, sizeof(sin) ) == SOCKET_ERROR ) { return 0; } //第五步:接收数据 char szBuf[1024]; sockaddr_in addr; int nLen = sizeof(addr); while (true) { int nRecv = recvfrom(sServer, szBuf, 1024, 0, (sockaddr*)&addr, &nLen); if ( nRecv > 0 ) { szBuf[nRecv] = '\0'; cout << "接收到数据:" << szBuf << endl; if ( strcmp(szBuf, "exit") == 0 ) { break; } } } //第六步:关闭socket,释放网络 closesocket(sServer); WSACleanup(); return 0; } |
客户端:
//ClientMain.cpp #include <stdio.h> #include <WinSock2.h> #include <iostream> #pragma comment(lib, "WS2_32.lib") using namespace std; int main() { //初始化网络 WSADATA wsaData; WORD wVersion = MAKEWORD(2,2); WSAStartup(wVersion, &wsaData); //建立一个socket SOCKET sClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //填充sockaddr_in结构 sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.S_un.S_addr = INADDR_ANY; sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); sin.sin_port = ntohs(16568); //发送数据 char szBuf[256]; while ( true ) { cin >> szBuf; ::sendto( sClient, szBuf, strlen(szBuf), 0, (sockaddr*)&sin, sizeof(sin) ); if(strcmp(szBuf, "exit") == 0 ) { break; } } //关闭socket closesocket(sClient); WSACleanup(); return 0; } |
就这么简单,一个简化的网络程序就写出来了。当然要完成完备的网络通信软件或者其他网络应用软件要比这个复杂,但是这也是通向复杂的开始。很多朋友接触网络编程的时候,感到很痛苦,因为可能一开始看得程序示例实现的功能比较全面,代码量一大反而可能不便于理解,这也是很多人一开始在学网络编程时畏惧网络编程的原因吧。
这里面涉及到的WSA(Win Socket API)函数就是如下几个:
WSAStartup()
socket()
bind()
recvfrom()
sendto()
closesocket()
WSACleanup()
htons()(与其同类的功能还有htonl、ntohs、ntohl都是网络字节顺序和主机字节顺序相互转换的函数)
然后是几个结构体。
这样我们在学起来的时候就清晰了。只要搞清楚上面列举的几个函数和其参数的使用,我们网络编程的入门第一步就算是完成了。希望我这贴给和我一样的新手一个启发。
我的建议是大家先写一遍代码,在写的过程中加深印象,然后在看MSDN或相关书籍详细的将每个WSA提供的那几个函数的说明看一遍,我的方法就是先实际操作一遍,在来看他的原理。这样最容易学习了。