基于UDP的效勞器端和客戶端

后面的文章中我們給出了幾個(gè)TCP的例子,關(guān)于UDP而言,只需能了解后面的內(nèi)容,完成并責(zé)難事。

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、六盤水網(wǎng)絡(luò)推廣、小程序開發(fā)、六盤水網(wǎng)絡(luò)營(yíng)銷、六盤水企業(yè)策劃、六盤水品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供六盤水建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:bm7419.com

UDP中的效勞器端和客戶端沒有銜接

UDP不像TCP,無(wú)需在銜接形態(tài)下交流數(shù)據(jù),因而基于UDP的效勞器端和客戶端也無(wú)需經(jīng)由銜接進(jìn)程。也就是說(shuō),不用挪用 listen() 和 accept() 函數(shù)。UDP中只要?jiǎng)?chuàng)立套接字的進(jìn)程和數(shù)據(jù)交流的進(jìn)程。

UDP效勞器端和客戶端均只需1個(gè)套接字

TCP中,套接字是一對(duì)一的關(guān)系。如要向10個(gè)客戶端供給效勞,那么除了擔(dān)任監(jiān)聽的套接字外,還需求創(chuàng)立10套接字。但在UDP中,不論是效勞器端照樣客戶端都只需求1個(gè)套接字。之前說(shuō)明UDP道理的時(shí)分舉了郵寄包裹的例子,擔(dān)任郵寄包裹的快遞公司可以比方為UDP套接字,只需有1個(gè)快遞公司,就可以經(jīng)過(guò)它向恣意地址郵寄包裹。異樣,只需1個(gè)UDP套接字就可以向恣意主機(jī)傳送數(shù)據(jù)。

基于UDP的接納和發(fā)送函數(shù)

創(chuàng)立好TCP套接字后,傳輸數(shù)據(jù)時(shí)無(wú)需再添加地址信息,由于TCP套接字將堅(jiān)持與對(duì)方套接字的銜接。換言之,TCP套接字曉得目的地址信息。但UDP套接字不會(huì)堅(jiān)持銜接形態(tài),每次傳輸數(shù)據(jù)都要添加目的地址信息,這相當(dāng)于在郵寄包裹前填寫收件人地址。
發(fā)送數(shù)據(jù)運(yùn)用 sendto() 函數(shù):

			ssize_t sendto(int sock, void *buf, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen); //Linux int sendto(SOCKET sock, const char *buf, int nbytes, int flags, const struct sockadr *to, int addrlen); //Windows

Linux和Windows下的 sendto() 函數(shù)相似,下面是具體參數(shù)闡明:

  • sock:用于傳輸U(kuò)DP數(shù)據(jù)的套接字;

  • buf:保管待傳輸數(shù)據(jù)的緩沖區(qū)地址;

  • nbytes:帶傳輸數(shù)據(jù)的長(zhǎng)度(以字節(jié)計(jì));

  • flags:可選項(xiàng)參數(shù),若沒有可傳遞0;

  • to:存有目的地址信息的 sockaddr 構(gòu)造體變量的地址;

  • addrlen:傳遞給參數(shù) to 的地址值構(gòu)造體變量的長(zhǎng)度。


UDP 發(fā)送函數(shù) sendto() 與TCP發(fā)送函數(shù) write()/send() 的最大差別在于,sendto() 函數(shù)需求向他傳遞目的地址信息。
接納數(shù)據(jù)運(yùn)用 recvfrom() 函數(shù):

			ssize_t recvfrom(int sock, void *buf, size_t nbytes, int flags, struct sockadr *from, socklen_t *addrlen); //Linux int recvfrom(SOCKET sock, char *buf, int nbytes, int flags, const struct sockaddr *from, int *addrlen); //Windows

因?yàn)閁DP數(shù)據(jù)的發(fā)送端不不定,所以 recvfrom() 函數(shù)界說(shuō)為可接納發(fā)送端信息的方式,詳細(xì)參數(shù)如下:

  • sock:用于接納UDP數(shù)據(jù)的套接字;

  • buf:保管接納數(shù)據(jù)的緩沖區(qū)地址;

  • nbytes:可接納的最大字節(jié)數(shù)(不克不及超越buf緩沖區(qū)的巨細(xì));

  • flags:可選項(xiàng)參數(shù),若沒有可傳遞0;

  • from:存有發(fā)送端地址信息的sockaddr構(gòu)造體變量的地址;

  • addrlen:保管參數(shù) from 的構(gòu)造體變量長(zhǎng)度的變量地址值。

基于UDP的反響效勞器端/客戶端

下面聯(lián)合之前的內(nèi)容完成反響客戶端。需求留意的是,UDP分歧于TCP,不存在懇求銜接和受理進(jìn)程,因而在某種意義上無(wú)法明白辨別效勞器端和客戶端,只是由于其供給效勞而稱為效勞器端,愿望列位讀者不要曲解。
下面給出Windows下的代碼,Linux與此相似,不再贅述。
效勞器端 server.cpp:

			#include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib") //加載 ws2_32.dll #define BUF_SIZE 100 int main(){ WSADATA wsaData; WSAStartup( MAKEWORD(2, 2), &wsaData); //創(chuàng)立套接字 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); //綁定套接字 sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); //每一個(gè)字節(jié)都用0填充 servAddr.sin_family = PF_INET; //運(yùn)用IPv4地址 servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //主動(dòng)獲取IP地址 servAddr.sin_port = htons(1234); //端口 bind(sock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR)); //接納客戶端懇求 SOCKADDR clntAddr; //客戶端地址信息 int nSize = sizeof(SOCKADDR); char buffer[BUF_SIZE]; //緩沖區(qū) while(1){ int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &clntAddr, &nSize); sendto(sock, buffer, strLen, 0, &clntAddr, nSize); } closesocket(sock); WSACleanup(); return 0; }

代碼闡明:
1) 第12行代碼在創(chuàng)立套接字時(shí),向 socket() 第二個(gè)參數(shù)傳遞 SOCK_DGRAM,以指明運(yùn)用UDP協(xié)定。
2) 第18行代碼中運(yùn)用htonl(INADDR_ANY)來(lái)主動(dòng)獲取IP地址。
應(yīng)用常數(shù) INADDR_ANY 主動(dòng)獲取IP地址有一個(gè)分明的益處,就是當(dāng)軟件裝置到其他效勞器或許效勞器IP地址改動(dòng)時(shí),不必再更改源碼從新編譯,也不必在啟動(dòng)軟件時(shí)手動(dòng)輸出。并且,假如一臺(tái)盤算機(jī)中已分派多個(gè)IP地址(例如路由器),那么只需端標(biāo)語(yǔ)分歧,就可以從分歧的IP地址接納數(shù)據(jù)。所以,效勞器中優(yōu)先思索運(yùn)用INADDR_ANY;而客戶端中除非帶有一局部效勞器功用,不然不會(huì)采取。
客戶端 client.cpp:

			#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") //加載 ws2_32.dll #define BUF_SIZE 100 int main(){ //初始化DLL WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); //創(chuàng)立套接字 SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0); //效勞器地址信息 sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); //每一個(gè)字節(jié)都用0填充 servAddr.sin_family = PF_INET; servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servAddr.sin_port = htons(1234); //不時(shí)獲取用戶輸出并發(fā)送給效勞器,然后承受效勞器數(shù)據(jù) sockaddr fromAddr; int addrLen = sizeof(fromAddr); while(1){ char buffer[BUF_SIZE] = {0}; printf("Input a string: "); gets(buffer); sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&servAddr, sizeof(servAddr)); int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &fromAddr, &addrLen); buffer[strLen] = 0; printf("Message form server: %s\n", buffer); } closesocket(sock); WSACleanup(); return 0; }

先運(yùn)轉(zhuǎn) server,再運(yùn)轉(zhuǎn) client,client 輸入后果為:

Input a string: C言語(yǔ)中文網(wǎng)
Message form server: C言語(yǔ)中文網(wǎng)
Input a string: c.biancheng.net Founded in 2012
Message form server: c.biancheng.net Founded in 2012
Input a string:


從代碼中可以看出,server.cpp 中沒有運(yùn)用 listen() 函數(shù),client.cpp 中也沒有運(yùn)用 connect() 函數(shù),由于 UDP 不需求銜接。

網(wǎng)站名稱:基于UDP的效勞器端和客戶端
當(dāng)前鏈接:http://bm7419.com/article12/gocsgc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、自適應(yīng)網(wǎng)站、靜態(tài)網(wǎng)站全網(wǎng)營(yíng)銷推廣、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)