winsocket分為流套接字和數據報套接字。winsocket編程一般都采用C/S模式。
在server端的流程一般如下:
1、初始化winsocket
2、建立socket
3、與本機進行邦定(bind)
4、開始監聽(listen)
5、然后與客戶端建立連接(accept)
6、然后與客戶端進行通信(send, recv)
7、當通信完成以后,關閉連接
8、釋放winsocket的有關資源
在Client端的流程一般如下:
1、初始化winsocket
2、建立socket
3、與本機進行邦定(bind)
4、與服務器進行連接(connect)
5、與服務器進行通信(send, recv)
6、當通信完成以后,關閉連接
7、釋放winsocket占用的資源
和JAVA的網絡編程相比我發現了有三個不一樣的地方,在JAVA中服務器端的socket是一個serverSocket Class,Client端建立的socket是socket Class;在JAVA中沒有第一步(初始化)和第三步(bind)過程。
之所以需要初始化winsocket,是因為Winsock的服務是以動態連接庫Winsock DLL形式實現的,所以必須先調用初始化函數(WSAStartup)對Winsock DLL進行初始化,協商Winsock的版本支持,並分配必要的資源;關於第三步中的bind過程,當套接字(socket)創建以后,該套接字並沒有與本機地址和端口等信息相聯,bind過程將完成這一任務。
現在開始我的第一個程序,進行Windows網絡編程,需要在的程序中包含winsock2.h或mswsock.h頭文件,同時你需要添加引入ws2_32.lib或winsock32.lib庫文件,他們分別在Microsoft Visual Studio 8\VC\PlatformSDK\Lib
我程序的功能就是實現client和server進行連接,當連接上了,在兩端分別顯示連接成功(主要是為了熟悉上面的流程)
Server端的代碼:
#include "stdafx.h" #include "WinSock2.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; SOCKET ListeningSocket; SOCKADDR_IN ServerAddr; SOCKET NewConnection; SOCKADDR_IN ClientAddr; int Port = 5150; WSAStartup(MAKEWORD(2, 2), &wsaData);// 初始化Windows Socket 2.2 ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//創建一個新的Socket來響應 客戶端的連接請求;AF_INET字段是表示網絡地址的類型,AF_INET表示是internet域中進行通信;SOCK_STREAM表示socket的類型,SOCK_STREAM表示是流套接字IPPROTO_TCP表明協議類型,IPPROTO_TCP或者0表示TCP/IP協議 ServerAddr.sin_family = AF_INET; // 填寫服務器地址信 ServerAddr.sin_port = htons(Port); // 端口為5150 ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY表示機器上的所用網絡地址 ; 比如你的機器上有兩張網卡,那么到達這兩張網卡的數據,你的socket都可以得到通知;htonl將IP地址轉換為網絡格式 bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)); //綁定監聽端口;當調用socket函數創建套接字后,該套接字並沒有與本機地址和端口等信息相連,bind函數將完成這些工作 listen(ListeningSocket, 2); // 開始監聽,指定最大同時連接數為2 int len = sizeof(ClientAddr); NewConnection = accept(ListeningSocket, (SOCKADDR *)&ClientAddr, &len);// 接受新的連接 cout << "************************************************" << endl; cout << "****new client has been connected******" << endl; cout << "*************************************************" << endl; /* 當連接建立之后,我們就可以在這里和client進行通信,傳輸數據了*/ closesocket(NewConnection); //關閉連接 closesocket(ListeningSocket); //並關閉監聽Socket WSACleanup(); // 釋放Windows Socket DLL的相關資源 return 0; }
Client端代碼:
#include "stdafx.h" #include "WinSock2.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; SOCKET s; SOCKADDR_IN ServerAddr; int Port = 5150; WSAStartup(MAKEWORD(2, 2), &wsaData); //初始化Windows Socket 2.2 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 創建一個新的Socket來連接服務器 ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //在程序中我與本機進行通信 int result = connect(s, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)); // 向服務器發出連接請求 if (result == 0){ //result==0表示連接成功 cout << "Client has connected to server!"; } closesocket(s); WSACleanup(); return 0; }
總結:建立網絡連接的過程
連接ws2_32.lib
scoket 建立套接字
bind綁定套接字
listen套接字監聽
accept接受連接請求
connect發起連接請求
send發送數據
recv接收數據