日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Socket编程基本流程实践

發(fā)布時(shí)間:2025/4/5 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Socket编程基本流程实践 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

通訊基本流程圖如下所示:

Server端代碼(ServerDemo.cpp):

1 #include <WinSock2.h> 2 #include <Windows.h> 3 #include <iostream> 4 #include <string> 5 #include <sstream> 6 7 using namespace std; 8 9 #pragma comment(lib, "WS2_32.lib") 10 11 int main() 12 { 13 /* 14 WSAstartup 必須是應(yīng)用程序首先調(diào)用的 Winsock 函數(shù)。它允許應(yīng)用程序指定所需的 15 Windows Sockets API 的版本,獲取特定 Winsock 實(shí)現(xiàn)的詳細(xì)信息。僅當(dāng)這個(gè)函數(shù)成功執(zhí)行之 16 后,應(yīng)用程序才能調(diào)用其他 Winsock API 17 每一個(gè)對(duì)WSAStartup的調(diào)用必須對(duì)應(yīng)一個(gè)對(duì)WSACleanup的調(diào)用, 這個(gè)函數(shù)釋放Winsock庫(kù)。 18 */ 19 WORD wVersion = MAKEWORD(2, 2); 20 WSADATA WSAData; 21 ::WSAStartup(wVersion, &WSAData); 22 23 stringstream os; 24 cout << "初始化套接字...." << endl; 25 SOCKET s; 26 s = ::socket(AF_INET, SOCK_STREAM, 0); 27 if(s == INVALID_SOCKET) 28 { 29 cout << "socket fail!" << endl; 30 goto __end; 31 } 32 sockaddr_in addr_in; 33 addr_in.sin_family = AF_INET; //設(shè)置地址家族 34 addr_in.sin_addr.S_un.S_addr = INADDR_ANY; 35 addr_in.sin_port = htons(8080); // 轉(zhuǎn)化端口號(hào)8080到網(wǎng)絡(luò)字節(jié)順序,并安排它到正確的成員 36 37 // 綁定這個(gè)套節(jié)字到一個(gè)本地地址 38 cout << "綁定端口8080...." << endl; 39 if(::bind(s, (LPSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR) 40 { 41 cout << "bind error!" << endl; 42 goto __end; 43 } 44 45 // listen 函數(shù)置套節(jié)字進(jìn)入監(jiān)聽狀態(tài) 46 os << "開始監(jiān)聽...." << inet_ntoa(addr_in.sin_addr) << endl; //inet_ntoa() 將32 位的二進(jìn)制數(shù)轉(zhuǎn)化為字符串 47 cout << os.str() << endl; 48 if(::listen(s, 2) == SOCKET_ERROR) 49 { 50 cout << "listen error!" << endl; 51 goto __end; 52 } 53 54 SOCKET s_client; 55 sockaddr_in addr_client; 56 char szServerMsg[256] = "Hello client, this is server!"; 57 int nMsgLen = sizeof(szServerMsg); 58 while(true) 59 { 60 // accept 函數(shù)用于接受到來的連接。 61 if ((s_client = ::accept(s, (LPSOCKADDR)&addr_client, &nMsgLen)) == SOCKET_ERROR) 62 { 63 cout << "accept error!" << endl; 64 goto __end; 65 } 66 os.str(""); 67 os.clear(); 68 os << "接收到來自" << inet_ntoa(addr_client.sin_addr) << "的連接!"; 69 cout << os.str() << endl; 70 // send 函數(shù)在一個(gè)連接的套節(jié)字上發(fā)送緩沖區(qū)內(nèi)的數(shù)據(jù),返回發(fā)送數(shù)據(jù)的實(shí)際字節(jié)數(shù)。flag參數(shù)通常設(shè)置為0 71 ::send(s_client, szServerMsg, 256, 0); 72 ::closesocket(s_client); 73 } 74 ::closesocket(s); 75 76 __end: 77 ::WSACleanup(); 78 system("pause"); 79 return 0; 80 }

Client端代碼(ClientDemo.cpp)

1 #include <WinSock2.h> 2 #include <Windows.h> 3 #include <iostream> 4 #include <string> 5 #include <sstream> 6 7 #pragma comment(lib, "WS2_32.lib") 8 9 using namespace std; 10 11 int main() 12 { 13 WORD wVersion = MAKEWORD(2, 2); 14 WSADATA WSAData; 15 ::WSAStartup(wVersion, &WSAData); 16 SOCKET s = ::socket(AF_INET, SOCK_STREAM, 0); 17 if (s == INVALID_SOCKET) 18 { 19 cout << "socket fail!" << ::WSAGetLastError() << endl; 20 ::WSACleanup(); 21 return 0; 22 } 23 sockaddr_in serverAddr; 24 // inet_addr函數(shù)轉(zhuǎn)化一個(gè)"aa.bb.cc.dd"類型的IP地址字符串到長(zhǎng)整型,它是以網(wǎng)絡(luò)字節(jié)順序記錄的IP地址, 25 // sin_addr.S_un.S_addr指定了地址聯(lián)合中的此長(zhǎng)整型 26 serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 27 serverAddr.sin_family = AF_INET; 28 serverAddr.sin_port = htons(8080); 29 30 // 客戶端程序在創(chuàng)建套節(jié)字之后,要使用 connect 函數(shù)請(qǐng)求與服務(wù)器連接 31 if (::connect(s, (LPSOCKADDR)&serverAddr, sizeof(sockaddr_in))) 32 { 33 cout << "connect server fail!" << endl; 34 ::WSACleanup(); 35 return 0; 36 } 37 38 char buf[256]; 39 // recv 函數(shù)從對(duì)方接收數(shù)據(jù),并存儲(chǔ)它到指定的緩沖區(qū)。flag參數(shù)通常設(shè)置為0 40 ::recv(s, buf, 256, 0); 41 stringstream os; 42 os << "從服務(wù)器接收到數(shù)據(jù):" << buf; 43 cout << os.str() << endl; 44 45 system("pause"); 46 return 0; 47 }

?

  TCP 協(xié)議由于可靠、穩(wěn)定的特征而被用在大部分場(chǎng)合,但它對(duì)系統(tǒng)資源要求比較高。UDP
協(xié)議是一個(gè)簡(jiǎn)單的面向數(shù)據(jù)報(bào)的傳輸層協(xié)議,又叫用戶數(shù)據(jù)報(bào)協(xié)議。它提供了無連接的、不可
靠的數(shù)據(jù)傳輸服務(wù)。無連接是指他不像 TCP 協(xié)議那樣在通信前先與對(duì)方建立連接以確定對(duì)方
的狀態(tài)。不可靠是指它直接安裝指定 IP 地址和端口號(hào)將數(shù)據(jù)包發(fā)出去,如果對(duì)方不在線的話
數(shù)據(jù)就可能丟失。UDP 協(xié)議編程流程如下:
1.服務(wù)器端
(1)創(chuàng)建套節(jié)字(socket) 。
(2)綁定 IP 地址和端口(bind) 。
(3)收發(fā)數(shù)據(jù)(sendto/recvfrom) 。
(4)關(guān)閉連接 (closesocket) 。
2.客戶端
(1)創(chuàng)建套節(jié)字(socket) 。
(2)收發(fā)數(shù)據(jù)(sendto/recvfrom) 。
(3)關(guān)閉連接(closesocket) 。
UDP 協(xié)議用于發(fā)送和接收數(shù)據(jù)的函數(shù)是 sendto 和 recvfrom。它們的原形如下。
int sendto (
SOCKET s, // 用來發(fā)送數(shù)據(jù)的套節(jié)字
const char FAR * buf, // 指向發(fā)送數(shù)據(jù)的緩沖區(qū)
int len, // 要發(fā)送數(shù)據(jù)的長(zhǎng)度
int flags, // 一般指定為0
const struct sockaddr * to, // 指向一個(gè)包含目標(biāo)地址和端口號(hào)的sockaddr_in結(jié)構(gòu)
int tolen // 為 sockaddr_in 結(jié)構(gòu)的大小
);
同樣 UDP 協(xié)議接收數(shù)據(jù)也需要知道通信對(duì)端的地址信息。
int recvfrom (SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen);
這個(gè)函數(shù)不同于 recv 函數(shù)的是多出來的最后兩個(gè)參數(shù),from 參數(shù)是指向 sockaddr_in 結(jié)
構(gòu)的指針,函數(shù)在這里返回?cái)?shù)據(jù)發(fā)送方的地址,fromlen 參數(shù)用于返回前面的 sockaddr_in 結(jié)構(gòu)
的長(zhǎng)度。
與 TCP 協(xié)議相比,UDP 協(xié)議簡(jiǎn)單多了,編程細(xì)節(jié)就不詳細(xì)介紹了。

TCPClient封裝類(tcpClient.hpp):

1 #ifndef __TCP_CLIENT_H__ 2 #define __TCP_CLIENT_H__ 3 4 #include <winsock2.h> 5 #include <stdio.h> 6 #include <iostream> 7 8 class CTcpClient 9 { 10 public: 11 std::string m_strErrInfo;//錯(cuò)誤信息 12 13 CTcpClient() 14 { 15 WSAData wsaData; 16 if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0) 17 { 18 m_strErrInfo = "WSAStartup失敗"; 19 printf(m_strErrInfo.c_str()); 20 } 21 if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) 22 { 23 m_strErrInfo = "WSAStartup SOCKET版本不對(duì)"; 24 printf(m_strErrInfo.c_str()); 25 } 26 } 27 28 ~CTcpClient() 29 { 30 WSACleanup(); 31 } 32 33 int SendData(const char *pAddr, const char *pPort 34 , int iSendTimeOut, int iRecvTimeOut 35 , const char *pSendData, int nSendLen 36 , char *pRecvData, int nRecevLen) 37 { 38 int iTimeOut; 39 struct sockaddr_in addrServer; 40 m_strErrInfo=""; 41 int nRet = 0; 42 43 //創(chuàng)建SOCKET 44 SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0); 45 do 46 { 47 if(sockClient == INVALID_SOCKET) 48 { 49 m_strErrInfo = "socket創(chuàng)建失失敗"; 50 nRet = -1; 51 break; 52 } 53 //連接到服務(wù)器 54 memset(&addrServer,0,sizeof(sockaddr_in)); 55 addrServer.sin_family = AF_INET; 56 addrServer.sin_addr.s_addr = inet_addr(pAddr); 57 addrServer.sin_port = htons(atoi(pPort)); 58 59 if(connect(sockClient,(const struct sockaddr *)&addrServer,sizeof(sockaddr)) != 0) 60 { 61 nRet = -2; 62 m_strErrInfo = "連接到服務(wù)器失敗."; 63 break; 64 } 65 //設(shè)置發(fā)送超時(shí) 66 iTimeOut = iSendTimeOut; 67 68 if(::setsockopt(sockClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&iTimeOut,sizeof(iTimeOut))==SOCKET_ERROR) 69 { 70 m_strErrInfo = "setsockopt失敗"; 71 nRet = -3; 72 break; 73 } 74 //設(shè)置接收超時(shí) 75 iTimeOut = iRecvTimeOut; 76 77 if(::setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&iTimeOut,sizeof(iTimeOut))==SOCKET_ERROR) 78 { 79 m_strErrInfo = "setsockopt失敗"; 80 nRet = -4; 81 break; 82 } 83 //發(fā)送請(qǐng)求 84 if(send(sockClient, pSendData, nSendLen * sizeof(char), 0) <= 0) 85 { 86 m_strErrInfo = "發(fā)送失敗."; 87 nRet = -5; 88 break; 89 } 90 91 //接收服務(wù)端應(yīng)答 92 memset(pRecvData, 0, nRecevLen * sizeof(char)); 93 int rc = SOCKET_ERROR; 94 int cnt = nRecevLen * sizeof(char); 95 96 while(cnt > 0) 97 { 98 rc = recv(sockClient, pRecvData, nRecevLen * sizeof(char), 0); 99 100 if(rc == SOCKET_ERROR) 101 { 102 m_strErrInfo = "接收失敗"; 103 nRet = -6; 104 break; 105 } 106 if(rc == 0) 107 { 108 if(nRet <= 0) 109 { 110 nRet = -7; 111 m_strErrInfo = "后臺(tái)無應(yīng)答"; 112 } 113 //nRet = ( ? -7 : nRet); 114 break; 115 } 116 nRet += rc; 117 pRecvData += rc; 118 cnt -= rc; 119 } 120 121 }while (0); 122 123 closesocket(sockClient); 124 return nRet; 125 } 126 127 int SendData(const char *pAddr, const char *pPort 128 , int iSendTimeOut, int iRecvTimeOut 129 , const char *pSendData, std::string &strRecv, int iMulRecv = 0) 130 { 131 int iRet; 132 int iTimeOut; 133 struct sockaddr_in addrServer; 134 char szRecvDataBuf[1024*64+1]; 135 136 m_strErrInfo=""; 137 138 //創(chuàng)建SOCKET 139 SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0); 140 if(sockClient == INVALID_SOCKET) 141 { 142 m_strErrInfo = "socket創(chuàng)建失敗"; 143 return -1; 144 } 145 146 //連接到服務(wù)器 147 memset(&addrServer,0,sizeof(sockaddr_in)); 148 addrServer.sin_family = AF_INET; 149 addrServer.sin_addr.s_addr = inet_addr(pAddr); 150 addrServer.sin_port = htons(atoi(pPort)); 151 if(connect(sockClient,(const struct sockaddr *)&addrServer,sizeof(sockaddr)) != 0) 152 { 153 m_strErrInfo = "連接服務(wù)器失敗"; 154 goto _end; 155 } 156 157 //設(shè)置發(fā)送超時(shí) 158 iTimeOut = iSendTimeOut; 159 if(::setsockopt(sockClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&iTimeOut,sizeof(iTimeOut))==SOCKET_ERROR) 160 { 161 m_strErrInfo = "setsockopt失敗"; 162 goto _end; 163 } 164 //設(shè)置接收超時(shí) 165 iTimeOut = iRecvTimeOut; 166 if(::setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&iTimeOut,sizeof(iTimeOut))==SOCKET_ERROR) 167 { 168 m_strErrInfo = "setsockopt失敗"; 169 goto _end; 170 } 171 172 //發(fā)送請(qǐng)求 173 if(send(sockClient, pSendData, strlen(pSendData), 0) <= 0) 174 { 175 m_strErrInfo = "發(fā)送失敗"; 176 goto _end; 177 } 178 179 //接收服務(wù)端應(yīng)答 180 strRecv = ""; 181 do 182 { 183 memset(szRecvDataBuf, 0, sizeof(szRecvDataBuf)); 184 iRet = recv(sockClient, szRecvDataBuf, sizeof(szRecvDataBuf)-1, 0); 185 strRecv += szRecvDataBuf; 186 } while (iRet > 0 && iMulRecv); 187 if(0 == strRecv.length()) 188 { 189 m_strErrInfo = "接收失敗"; 190 } 191 192 //關(guān)閉SOCKET 193 closesocket(sockClient); 194 return 0; 195 196 _end: 197 closesocket(sockClient); 198 return -1; 199 } 200 201 std::string GetIPAddrByDNS(const char *pDNS) 202 { 203 //通過域名得到IP地址 204 std::string strAddr; 205 WSADATA wsadata; 206 WSAStartup(MAKEWORD(2,2),&wsadata); 207 hostent *phost=gethostbyname(pDNS); 208 if(phost) 209 { 210 in_addr addr; 211 for(int i=0;;i++) 212 { 213 char *p=phost->h_addr_list[i]; 214 if(p==NULL) break; 215 memcpy(&addr.S_un.S_addr,p,phost->h_length); 216 char* ip=inet_ntoa(addr); 217 strAddr = ip; 218 219 if (strAddr.length()) 220 break; 221 } 222 } 223 return strAddr; 224 } 225 }; 226 #endif

?

?

?

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的Socket编程基本流程实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 长腿校花无力呻吟娇喘的视频 | 97伊人久久 | 爱福利视频一区 | 久久视频网 | 亚洲狼人综合网 | 久久福利电影 | 国产精品va无码一区二区三区 | 性生活视频在线播放 | 太久av| 激情在线观看视频 | 性色av一区二区三区在线观看 | 免费观看黄色的网站 | 黄色大片网 | 91久久免费 | 美女免费av | 欧美aⅴ在线观看 | 亚洲国产精品自拍视频 | 日本妇乱大交xxxxx | 国产精品久久久久久久久久久免费看 | 国产呦系列 | 69av在线 | 久久久久久国产免费a片 | 91视频插插插 | 黑人添美女bbb添高潮了 | 无码一区二区三区免费视频 | 日本在线观看一区二区 | 日韩视频在线观看 | 国外成人性视频免费 | 成人免费毛片嘿嘿连载视频 | 一区二区视频免费 | 另类小说一区二区 | 亚洲一区二区三区久久 | 国产孕妇一区二区三区 | 九九自拍偷拍 | 午夜精品免费 | 久草免费在线视频观看 | 国产chinasex麻豆videos | 国产乱人视频 | 老司机免费在线视频 | 成年人黄色免费网站 | 超黄av| 日韩av看片 | 久久久久久久综合色一本 | 中文字幕亚洲无线码在线一区 | 欧美视频在线一区 | 日韩中文字幕视频在线 | 七仙女欲春2一级裸体片 | 丁香综合激情 | 欧美伦理一区 | 国产亚洲欧美一区 | 成人乱码一区二区三区av | 欧美亚洲自拍偷拍 | 国产成年网站 | 免费看片黄色 | 日本黄色高清视频 | 俄罗斯毛片 | 大黄网站在线观看 | 亚洲国产综合网 | 久久av色 | 蜜臀在线一区二区三区 | 色爱综合网 | 男人的天堂2018| 福利一区福利二区 | 嫩草综合| av网站国产 | 激情草逼| av基地 | 国内91视频| 日本免费在线播放 | 色黄视频在线观看 | 狠狠av | 美女视频黄色免费 | 久久大香焦 | 欧美国产成人在线 | 成人爽a毛片一区二区 | 三年中文在线观看中文版 | 亚洲激情婷婷 | 明星毛片 | www.天堂av.com| 欧美一级免费看 | 久久久久成人精品免费播放动漫 | 欧美特一级 | 淫岳高潮记小说 | 欧美色图亚洲视频 | 狠狠的干狠狠的操 | 色多多入口 | 黄色网页大全 | 少妇毛片一区二区三区 | 国产成人免费看 | 欧美精品xxx| 天堂99| 理论片中文字幕 | 美女又黄又爽 | 无遮挡在线观看 | 日本三级视频在线观看 | 锕锕锕锕锕锕锕锕 | 伊人久久九 | 婷婷综合久久 | 国产免费内射又粗又爽密桃视频 |