介紹:
WinSock(Windows Sockets)API是一個微軟的windows系統介面編程庫。它最初是基於Berkeley sockets。但是微軟做了一些相應的改動。這裡我試圖簡單的介紹一下WinSock的編程技術,假定你已經開發過一些網路程式不論是什麼作業系統。
如果你只有一台機器,不用擔心,你仍然可以進行WinSock編程。你可以使用本地的地址localhost作為IP地址通常是127.0.0.1。如果你有你特TCP的伺服器在機器上運行,還可以運行一個用戶端程式在同一台電腦上。
簡單的TCP伺服器:
這裡我要通過一個簡單的TCP伺服器向你介紹一下WinSock,我會一步一步講。但在開始之前,你先要完成一點任務,然後在真正開始WinSock編程。
開始要用VC++ 6.0App Wizard建立一個 Win32的控制台程式。在這裡選擇support for MFC選項。
開啟stdafx.h檔案,添加#include <winsock2.h> 還有#include conio.h和iostream.h。使用Project-Settings-Link在其中的library modules list中添加ws2_32.lib。
以下是主程式:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
cout << "Press ESCAPE to terminate program/r/n";
AfxBeginThread(ServerThread,0);
while(_getch()!=27);
return nRetCode;
}
主程式是用來建立一個線程然後迴圈調用_getch()。_getch()一直等待直到得到一個鍵盤輸入的字元值。當得到ASCII值是27時返回,因為27的ASCII碼是ESCAPE鍵。你也許知道即使我按了ESCAPE,開始建立的線程也不會結束。這根本不用擔心。當main() 函數返回該線程將關閉同時我在開始建立的那個線程也會關閉。
伺服器線程函數:
我要做的是列出伺服器的線程,然後用注釋解釋每一行代碼。首先TCP伺服器是這樣工作的。它偵聽20248連接埠,這個可能湊巧和其它代碼的衝突。當一個用戶端串連時,伺服器將返回一個資訊到用戶端給出IP地址然後開始在20248連接埠上接收資料。在控制台上同時列印一行串連的用戶端的IP。當然你覺得寫這麼個程式毫無意義。你也許覺得它和windows系統中的SNDREC32.EXE程式一樣沒意義。如果這樣我會覺得你太挑剔。
CollapseUINT ServerThread(LPVOID pParam)
{
cout << "Starting up TCP server/r/n";
//一個SOCKET定義,其實是unsigned int的typedef
//在Unix系統中socket控制代碼也是這樣的類型
//因為這不可能在windows下從新定義類型所以一個統一的SOCKET類型被定義了
SOCKET server;
//WSADATA是一個在WSAStartup調用中填充資料的結構
WSADATA wsaData;
//sockaddr_in指定TCP/IP的socket地址。該協議的結構非常熟悉
sockaddr_in local;
//WSAStartup引入,第一個參數指定WinSock的版本,然後在程式中使用。
int wsaret=WSAStartup(0x101,&wsaData);
//WSAStartup在成功建立後返回0,如果不是就結束程式
if(wsaret!=0)
{
return 0;
}
//現在非常熟悉的sockaddr_in結構參數
local.sin_family=AF_INET; //Address family
local.sin_addr.s_addr=INADDR_ANY; //Wild card IP address
local.sin_port=htons((u_short)20248); //port to use
//用socket函數建立SOCKET
server=socket(AF_INET,SOCK_STREAM,0);
//如果失敗則退出程式
if(server==INVALID_SOCKET)
{
return 0;
}
//將建立的SOCKET幫定到sockaddr_in
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
//開始偵聽
if(listen(server,10)!=0)
{
return 0;
}
//再建立接受已經串連的用戶端的SOCKET
SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
while(true)//we are looping endlessly
{
char temp[512];
//當有資料時接受串連用戶端
client=accept(server,
(struct sockaddr*)&from,&fromlen);
sprintf(temp,"Your IP is %s/r/n",inet_ntoa(from.sin_addr));
//向用戶端發送一個字串
send(client,temp,strlen(temp),0);
cout << "Connection from " << inet_ntoa(from.sin_addr) <<"/r/n";
//關閉串連用戶端的socket
closesocket(client);
}
//關閉服務端socket
closesocket(server);
//通常調用WSACleanup來結束是比較安全的
WSACleanup();
return 0;
}
測試輸出:
在服務端得到如下輸出結果:
E:/work/Server/Debug>server
Press ESCAPE to terminate program
Starting up TCP server
Connection from 203.200.100.122
Connection from 127.0.0.1
E:/work/Server/Debug>
以下是客戶段的輸出結果:
nish@sumida:~$ telnet 202.89.211.88 20248
Trying 202.89.211.88...
Connected to 202.89.211.88.
Escape character is '^]'.
Your IP is 203.200.100.122
Connection closed by foreign host.
nish@sumida:~$
結束:
這樣,你知道了怎樣建立一個簡單的TCP伺服器了。如果更深一步我會介紹給你用 WinSock 建立更進階功能的程式。如果有人對該程式有疑問,請回複。