溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-07-19 18:46:09 來源:網絡 閱讀:547 作者:yuw2017 欄目:網絡安全

后面的文章中我們給出了幾個TCP的例子,關于UDP而言,只需能了解后面的內容,完成并責難事。

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

UDP不像TCP,無需在銜接形態下交流數據,因而基于UDP的效勞器端和客戶端也無需經由銜接進程。也就是說,不用挪用 listen() 和 accept() 函數。UDP中只要創立套接字的進程和數據交流的進程。

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

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

基于UDP的接納和發送函數

創立好TCP套接字后,傳輸數據時無需再添加地址信息,由于TCP套接字將堅持與對方套接字的銜接。換言之,TCP套接字曉得目的地址信息。但UDP套接字不會堅持銜接形態,每次傳輸數據都要添加目的地址信息,這相當于在郵寄包裹前填寫收件人地址。
發送數據運用 sendto() 函數:

			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() 函數相似,下面是具體參數闡明:

  • sock:用于傳輸UDP數據的套接字;

  • buf:保管待傳輸數據的緩沖區地址;

  • nbytes:帶傳輸數據的長度(以字節計);

  • flags:可選項參數,若沒有可傳遞0;

  • to:存有目的地址信息的 sockaddr 構造體變量的地址;

  • addrlen:傳遞給參數 to 的地址值構造體變量的長度。


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

			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

因為UDP數據的發送端不不定,所以 recvfrom() 函數界說為可接納發送端信息的方式,詳細參數如下:

  • sock:用于接納UDP數據的套接字;

  • buf:保管接納數據的緩沖區地址;

  • nbytes:可接納的最大字節數(不克不及超越buf緩沖區的巨細);

  • flags:可選項參數,若沒有可傳遞0;

  • from:存有發送端地址信息的sockaddr構造體變量的地址;

  • addrlen:保管參數 from 的構造體變量長度的變量地址值。

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

下面聯合之前的內容完成反響客戶端。需求留意的是,UDP分歧于TCP,不存在懇求銜接和受理進程,因而在某種意義上無法明白辨別效勞器端和客戶端,只是由于其供給效勞而稱為效勞器端,愿望列位讀者不要曲解。
下面給出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); //創立套接字 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); //綁定套接字 sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); //每一個字節都用0填充 servAddr.sin_family = PF_INET; //運用IPv4地址 servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //主動獲取IP地址 servAddr.sin_port = htons(1234); //端口 bind(sock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR)); //接納客戶端懇求 SOCKADDR clntAddr; //客戶端地址信息 int nSize = sizeof(SOCKADDR); char buffer[BUF_SIZE]; //緩沖區 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行代碼在創立套接字時,向 socket() 第二個參數傳遞 SOCK_DGRAM,以指明運用UDP協定。
2) 第18行代碼中運用htonl(INADDR_ANY)來主動獲取IP地址。
應用常數 INADDR_ANY 主動獲取IP地址有一個分明的益處,就是當軟件裝置到其他效勞器或許效勞器IP地址改動時,不必再更改源碼從新編譯,也不必在啟動軟件時手動輸出。并且,假如一臺盤算機中已分派多個IP地址(例如路由器),那么只需端標語分歧,就可以從分歧的IP地址接納數據。所以,效勞器中優先思索運用INADDR_ANY;而客戶端中除非帶有一局部效勞器功用,不然不會采取。
客戶端 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); //創立套接字 SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0); //效勞器地址信息 sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); //每一個字節都用0填充 servAddr.sin_family = PF_INET; servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servAddr.sin_port = htons(1234); //不時獲取用戶輸出并發送給效勞器,然后承受效勞器數據 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; }

先運轉 server,再運轉 client,client 輸入后果為:

Input a string: C言語中文網
Message form server: C言語中文網
Input a string: c.biancheng.net Founded in 2012
Message form server: c.biancheng.net Founded in 2012
Input a string:


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


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女