使用VC6實現基於winsock技術的伺服器客戶機模擬程式
阿新 • • 發佈:2018-12-03
網路程式設計課:實驗1。
程式已跑通,現貼出來詳細步驟:
1.開啟vc6,新建一個工程。開啟選單欄欄裡的File(檔案) - > New(新建) - > Projects。然後選擇Win32控制檯應用程式。
給工程起名tcpserver,選擇工程目錄(預設就可以)。之後的工程設定保持預設就好。
2.然後再檔案 - >新建 - >檔案。選擇C ++原始檔。
檔名稱為tcpserver的的,位置就儲存到剛才建立的工程下就好。
3.然後,開始寫伺服器端的程式碼。
#include<winsock2.h> #pragma comment(lib,"ws2_32.lib") #include<stdio.h> void main() { WSADATA wsadata; SOCKADDR_IN ServerAddr; //Internet通訊域的地址結構 SOCKET ListeningSocket; //監聽套接字 SOCKET NewConnection; SOCKADDR_IN ClientAddr; char DataBuffer[100]; int port = 6500; //監聽套接字的埠號 int Ret; int ClientAddrLen; memset(DataBuffer,0,100); //1.初始化伺服器網路環境,也稱為註冊 if((Ret = WSAStartup(MAKEWORD(2,2),&wsadata)) !=0)//MAKEWORD(2,2)指的是應用程式要使用的WinSock規範的最高版本 //WSADATA資料用來返回WinSock API實現的細節資訊 { printf("WSAStartup failed with error %d\n",Ret); return; } //2.建立伺服器監聽套接字 if((ListeningSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == SOCKET_ERROR) { printf("ListeningSocket failed with error:%d\n",WSAGetLastError()); WSACleanup(); return; } printf("ListeningSocket has been created!\n"); //3.初始化結構地址並與監聽套接字繫結 memset((char *)&ServerAddr,0,sizeof(ServerAddr)); ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(port); ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY代表本地IP地址 //4.繫結套接字 if(bind(ListeningSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR) { printf("bind failed with error %d\n",WSAGetLastError()); WSACleanup(); return; } //5.啟動監聽 if(listen(ListeningSocket,5) == SOCKET_ERROR) { printf("listen failed with error %d\n",WSAGetLastError()); WSACleanup(); return; } //6.接受客戶端連線請求並建立連線套接字 while(1) { ClientAddrLen = sizeof(ClientAddr); if((NewConnection = accept(ListeningSocket,(SOCKADDR *)&ClientAddr,&ClientAddrLen)) == SOCKET_ERROR) { printf("accept failed with error:%d",WSAGetLastError()); WSACleanup(); return; } recv(NewConnection,DataBuffer,sizeof(DataBuffer),0); printf("%s",DataBuffer); } //伺服器連線套接字接受客戶端資料 //關閉連線套接字和監聽套接字,釋放網路資源 closesocket(NewConnection); closesocket(ListeningSocket); WSACleanup(); return; }
之後,除錯執行一下。
4.再開啟一個VC6視窗,按照步驟1,2-再建立一個工程,只不過這次工程名變為TcpClient的的,CPP檔案變為TcpClient的的。
注意:不要試圖在原有的工程之上新建一個工程,因為這樣會覆蓋原來的工程最好是重新開啟一個VC6視窗!
5.寫客戶機端的程式碼,程式碼如下:
#include<winsock2.h> #pragma comment(lib,"ws2_32.lib") #include<stdio.h> void main(int argc,char **argv) { //資料結構定義 WSADATA wsadata; SOCKET s; //套接字描述符 SOCKADDR_IN ServerAddr; //伺服器地址 int Port = 6500; //埠是6500 int Ret; //1.初始化Winsock,也稱為註冊。如果初始化失敗,則輸出失敗資訊 if((Ret = WSAStartup(MAKEWORD(2,2),&wsadata)) != 0)//MAKEWORD(2,2)指的是應用程式要使用的WinSock規範的最高版本 { printf("WSAStartup failed with error %d\n",Ret); return; } //2.建立連線套接字 if((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET) { printf("socket failed with error %d\n",WSAGetLastError()); WSACleanup(); return; } //3.初始化目的端(伺服器)地址結構,先進行memset()清零操作,然後初始化 memset(&ServerAddr,0,sizeof(SOCKADDR_IN)); ServerAddr.sin_family = AF_INET; //使用的通訊域是AF_INET,代表Internet域 ServerAddr.sin_port = htons(Port); //目的地址的埠號是htons(Port),htons代表把 //本機順序轉化為網路順序,用於埠號 ServerAddr.sin_addr.s_addr = inet_addr("10.108.164.43");//設定伺服器Ip地址 //inet_addr()可以把點分十進位制IP地址轉化為無符號長整型 //inet_ntoa()相反 //提示資訊:正在試圖連線伺服器 printf("We are trying to connect to %s:%d...\n",inet_ntoa(ServerAddr.sin_addr),htons(ServerAddr.sin_port)); //4.然後向伺服器發出連線請求 if(connect(s,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR) { printf("connect failed with error %d\n",WSAGetLastError()); WSACleanup(); return; } //提示資訊:連線成功 printf("Our connection succeeded.\n"); //提示資訊:我們會發送一條訊息 printf("We will now try to send a hello message.\n"); //5.向伺服器傳送資料 if((Ret = send(s,"Hello,ServerXX\n",14,0)) == SOCKET_ERROR) { printf("send failed with error %d\n",WSAGetLastError()); closesocket(s); WSACleanup(); return; } //提示資訊:訊息傳送成功 printf("We have sent a %d byte(s).\n",Ret); //提示資訊:我們即將關閉連線 printf("We are closing connection\n"); //6.關閉連線套接字釋放網路資源 closesocket(s); WSACleanup(); }
除錯執行一下,不出錯就行。
注意:在第3點初始化這一步驟中,設定IP地址這一行中,程式碼要寫自己本機的IP地址如果不知道自己的IP地址,開啟命令管理器輸入IPCONFIG就可以看到自己的IP地址了。
6.然後,先執行的tcpserver的,再執行的TcpClient的。就可以看到連線成功的資訊了。
大功告成!
最後附上一張圖
不過Winsock的程式設計,多了兩個步驟,在建立套接字之前要進行註冊,呼叫WSAStartup(),關閉套接字之後要進行登出WSACleanup()。