Windows Socket 编程_ 简单的服务器/客户端程序
生活随笔
收集整理的這篇文章主要介紹了
Windows Socket 编程_ 简单的服务器/客户端程序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一。程序運行效果圖
//?server.cpp?? ?? #include?<iostream>?? #include?<cstdio>?? #include?<Winsock2.h>?? ?? using?namespace?std;?? ?? int?main()?? {?? //?加載socket動態鏈接庫(dll)?? ????WORD?wVersionRequested;?? ????WSADATA?wsaData;????//?這結構是用于接收Wjndows?Socket的結構信息的?? ????int?err;?? ??????? ????wVersionRequested?=?MAKEWORD(?1,?1?);???//?請求1.1版本的WinSock庫?? ??????? ????err?=?WSAStartup(?wVersionRequested,?&wsaData?);?? ????if?(?err?!=?0?)?{?? ????????return?-1;??????????//?返回值為零的時候是表示成功申請WSAStartup?? ????}?? ??????? ????if?(?LOBYTE(?wsaData.wVersion?)?!=?1?||?HIBYTE(?wsaData.wVersion?)?!=?1?)?{?? ????????//?檢查這個低字節是不是1,高字節是不是1以確定是否我們所請求的1.1版本?? ????????//?否則的話,調用WSACleanup()清除信息,結束函數?? ????????WSACleanup(?);?? ????????return?-1;??? ????}?? ?????? //?創建socket操作,建立流式套接字,返回套接字號sockSrv?? ????//?SOCKET?socket(int?af,?int?type,?int?protocol);?? ????//?第一個參數,指定地址簇(TCP/IP只能是AF_INET,也可寫成PF_INET)?? ????//?第二個,選擇套接字的類型(流式套接字),第三個,特定地址家族相關協議(0為自動)?? ????SOCKET?sockSrv?=?socket(AF_INET,?SOCK_STREAM,?0);????? ?? //?套接字sockSrv與本地地址相連?? ????//?int?bind(SOCKET?s,?const?struct?sockaddr*?name,?int?namelen);?? ????//?第一個參數,指定需要綁定的套接字;?? ????//?第二個參數,指定該套接字的本地地址信息,該地址結構會隨所用的網絡協議的不同而不同?? ????//?第三個參數,指定該網絡協議地址的長度?? ????//?PS:?struct?sockaddr{?u_short?sa_family;?char?sa_data[14];};?? ????//??????????????????????sa_family指定該地址家族,?sa_data起到占位占用一塊內存分配區的作用?? ????//?????在TCP/IP中,可使用sockaddr_in結構替換sockaddr,以方便填寫地址信息?? ????//??? ????//?????struct?sockaddr_in{?short?sin_family;?unsigned?short?sin_port;?struct?in_addr?sin_addr;?char?sin_zero[8];};?? ????//?????sin_family表示地址族,對于IP地址,sin_family成員將一直是AF_INET。?? ????//?????sin_port指定將要分配給套接字的端口。?? ????//?????sin_addr給出套接字的主機IP地址。?? ????//?????sin_zero[8]給出填充數,讓sockaddr_in與sockaddr結構的長度一樣。?? ????//?????將IP地址指定為INADDR_ANY,允許套接字向任何分配給本地機器的IP地址發送或接收數據。?? ????//?????如果想只讓套接字使用多個IP中的一個地址,可指定實際地址,用inet_addr()函數。?? ????SOCKADDR_IN?addrSrv;?? ????addrSrv.sin_addr.S_un.S_addr?=?htonl(INADDR_ANY);?//?將INADDR_ANY轉換為網絡字節序,調用?htonl(long型)或htons(整型)?? ????addrSrv.sin_family?=?AF_INET;?? ????addrSrv.sin_port?=?htons(6000);?? ?? ????bind(sockSrv,?(SOCKADDR*)&addrSrv,?sizeof(SOCKADDR));?//?第二參數要強制類型轉換?? ?? //?將套接字設置為監聽模式(連接請求),?listen()通知TCP服務器準備好接收連接?? ????//?int?listen(SOCKET?s,??int?backlog);?? ????//?第一個參數指定需要設置的套接字,第二個參數為(等待連接隊列的最大長度)?? ????listen(sockSrv,?10);?? ?? //?accept(),接收連接,等待客戶端連接?? ????//?SOCKET?accept(??SOCKET?s,??struct?sockaddr*?addr,??int*?addrlen);?? ????//?第一個參數,接收一個處于監聽狀態下的套接字?? ????//?第二個參數,sockaddr用于保存客戶端地址的信息?? ????//?第三個參數,用于指定這個地址的長度?? ????//?返回的是向與這個監聽狀態下的套接字通信的套接字?? ?? //?客戶端與用戶端進行通信?? ?? ????//?send(),?在套接字上發送數據?? ????//?int?send(?SOCKET?s,??const?char*?buf,??int?len,??int?flags);?? ????//?第一個參數,需要發送信息的套接字,?? ????//?第二個參數,包含了需要被傳送的數據,?? ????//?第三個參數是buffer的數據長度,?? ????//?第四個參數,一些傳送參數的設置?? ?? ????//?recv(),?在套接字上接收數據?? ????//?int?recv(??SOCKET?s,??char*?buf,??int?len,??int?flags);?? ????//?第一個參數,建立連接后的套接字,?? ????//?第二個參數,接收數據?? ????//?第三個參數,接收數據的長度,?? ????//?第四個參數,一些傳送參數的設置?? ?? ????SOCKADDR_IN??addrClient;?? ????int?len?=?sizeof(SOCKADDR);?? ?? ????while(true){????//?不斷等待客戶端請求的到來?? ????????SOCKET?sockConn?=?accept(sockSrv,?(SOCKADDR*)&addrClient,?&len);?? ?????????? ????????char?sendBuf[100];?? ????????sprintf(sendBuf,?"Welcome?%s?to?the?server?program~?\nNow,?let's?start?talking...\n",?inet_ntoa(addrClient.sin_addr));?? ????????send(sockConn,?sendBuf,?strlen(sendBuf)+1,?0);??//?發送顯示歡迎信息?? ?? ????????char?recvBuf[100];?? ????????recv(sockConn,?recvBuf,?100,?0);?? ????????printf("%s\n",?recvBuf);????????//?接收第一次信息?? ?? ????????char?*?sockConnName?=?"Client";?? ????????printf("我們可以聊五句話");?? ????????int?n?=?5;?? ????????while(n--){?? ????????????printf("還剩%d次:\n",?n+1);?? ????????????char?recvBuf[100];?? ????????????recv(sockConn,?recvBuf,?100,?0);?? ????????????printf("%s?Says:?%s\n",?sockConnName,?recvBuf);?????//?接收信息?? ?????????????? ????????????char?talk[100];?? ????????????printf("Please?enter?what?you?want?to?say?next(\"quit\"to?exit):");?? ????????????gets(talk);?? ????????????send(sockConn,?talk,?strlen(talk)+1,?0);????????????//?發送信息?? ????????????printf("\n");?? ????????}????????? ????????printf("\nEnd?talking...?\n");?? ????????closesocket(sockConn);?? ????}?? ?? ????printf("\n");?? ????system("pause");?? ????return?0;?? }?? //?client.cpp?? ?? #include?<iostream>?? #include?<cstdio>?? #include?<Winsock2.h>?? ?? using?namespace?std;?? ?? int?main()?? {?? //?加載socket動態鏈接庫(dll)?? ????WORD?wVersionRequested;?? ????WSADATA?wsaData;????//?這結構是用于接收Wjndows?Socket的結構信息的?? ????int?err;?? ??????? ????wVersionRequested?=?MAKEWORD(?1,?1?);???//?請求1.1版本的WinSock庫?? ??????? ????err?=?WSAStartup(?wVersionRequested,?&wsaData?);?? ????if?(?err?!=?0?)?{?? ????????return?-1;??????????//?返回值為零的時候是表示成功申請WSAStartup?? ????}?? ??????? ????if?(?LOBYTE(?wsaData.wVersion?)?!=?1?||?HIBYTE(?wsaData.wVersion?)?!=?1?)?{?? ????????//?檢查這個低字節是不是1,高字節是不是1以確定是否我們所請求的1.1版本?? ????????//?否則的話,調用WSACleanup()清除信息,結束函數?? ????????WSACleanup(?);?? ????????return?-1;??? ????}?? ?????? //?創建socket操作,建立流式套接字,返回套接字號sockClient?? ????//?SOCKET?socket(int?af,?int?type,?int?protocol);?? ????//?第一個參數,指定地址簇(TCP/IP只能是AF_INET,也可寫成PF_INET)?? ????//?第二個,選擇套接字的類型(流式套接字),第三個,特定地址家族相關協議(0為自動)?? ????SOCKET?sockClient?=?socket(AF_INET,?SOCK_STREAM,?0);?? ?? //?將套接字sockClient與遠程主機相連?? ????//?int?connect(?SOCKET?s,??const?struct?sockaddr*?name,??int?namelen);?? ????//?第一個參數:需要進行連接操作的套接字?? ????//?第二個參數:設定所需要連接的地址信息?? ????//?第三個參數:地址的長度?? ????SOCKADDR_IN?addrSrv;?? ????addrSrv.sin_addr.S_un.S_addr?=?inet_addr("127.0.0.1");??????//?本地回路地址是127.0.0.1;??? ????addrSrv.sin_family?=?AF_INET;?? ????addrSrv.sin_port?=?htons(6000);?? ????connect(sockClient,?(SOCKADDR*)&addrSrv,?sizeof(SOCKADDR));?? ?? ????char?recvBuf[100];?? ????recv(sockClient,?recvBuf,?100,?0);?? ????printf("%s\n",?recvBuf);?? ?? ????send(sockClient,?"Attention:?A?Client?has?enter...\n",?strlen("Attention:?A?Client?has?enter...\n")+1,?0);?? ?? ????printf("我們可以聊五句話");?? ????int?n?=?5;?? ????do{?? ????????printf("\n還剩%d次:",?n);?? ????????char?talk[100];?? ????????printf("\nPlease?enter?what?you?want?to?say?next(\"quit\"to?exit):");?? ????????gets(talk);?? ????????send(sockClient,?talk,?strlen(talk)+1,?0);??????????//?發送信息?? ?? ????????char?recvBuf[100];?? ????????recv(sockClient,?recvBuf,?100,?0);?? ????????printf("%s?Says:?%s\n",?"Server",?recvBuf);?????//?接收信息?? ????}while(--n);?? ?? ????printf("End?linking...\n");?? ????closesocket(sockClient);?? ????WSACleanup();???//?終止對套接字庫的使用?? ?? ????printf("\n");?? ????system("pause");?? ????return?0;?? }??
二。程序源代碼
三。程序設計相關基礎知識
??? 1.計算機網絡
??? 2.IP地址
??? 3.協議
??? 4.網絡體系結構
??? 5.TCP/IP體系結構與特點
??? 6.客戶機/服務器模式
??? 7.TCP/IP特點
??? 8.套接字的引入
??? 9.面向 連接/無連接 的套接字的系統調用時序圖/流程圖
?
一。程序運行效果圖
?
二。程序源代碼
[cpp]?view plaincopyprint?
?
?
三。程序設計相關基礎知識
1.計算機網絡
2.IP地址
3.協議
4.網絡體系結構
5.TCP/IP體系結構與特點
6.客戶機/服務器模式
7.TCP/IP特點
8.套接字的引入
9.面向 連接/無連接 的套接字的系統調用時序圖/流程圖
總結
以上是生活随笔為你收集整理的Windows Socket 编程_ 简单的服务器/客户端程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WORD中如何自动生成目录?
- 下一篇: XSHELL下直接下载文件到本地(Win