中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

基于UDP協議的網絡程序

發布時間:2020-06-15 00:23:45 來源:網絡 閱讀:811 作者:牛鼓簧 欄目:網絡安全

下圖是基于UDP協議的客戶端/服務器程序的一般流程:

圖1.1 UDP協議通信流程

基于UDP協議的網絡程序

UDP套接口是無連接的、不可靠的數據報協議;

既然他不可靠為什么還要用呢?其一:當應用程序使用廣播或多播時只能使用UDP協議;其二:由于他是無連接的,所以速度快。因為UDP套接口是無連接的,如果一方的數據報丟失,那另一方將無限等待,解決辦法是設置一個超時。

建立UDP套接口時socket函數的第二個參數應該是SOCK_DGRAM,說明是建立一個UDP套接口;由于UDP是無連接的,所以服務器端并不需要listen或accept函數。

使用UDP套接字編程可以實現基于TCP/IP協議的面向無連接的通信,它分為服務器端和客戶端兩部分,其主要實現過程如圖1.1所示。

下面介紹UDP網絡編程的詳細函數和過程:

 1、socket函數:為了執行網絡輸入輸出,一個進程必須做的第一件事就是調用socket函數獲得一個文件描述符。

-----------------------------------------------------------------
 #include <sys/socket.h>
 int socket(int family,int type,int protocol);    
      返回:非負描述字---成功   -1---失敗
 -----------------------------------------------------------------

第一個參數指明了協議簇,目前支持5種協議簇,最常用的有AF_INET(IPv4協議)和AF_INET6(IPv6協議);第二個參數指明套接口類型,有三種類型可選:SOCK_STREAM(字節流套接口)、SOCK_DGRAM(數據報套接口)和SOCK_RAW(原始套接口);如果套接口類型不是原始套接口,那么第三個參數就為0。

2、bind函數:為套接口分配一個本地IP和協議端口,對于網際協議,協議地址是32位IPv4地址或128位IPv6地址與16位的TCP或UDP端口號的組合;如指定端口為0,調用bind時內核將選擇一個臨時端口,如果指定一個通配IP地址,則要等到建立連接后內核才選擇一個本地IP地址。

-------------------------------------------------------------------
#include <sys/socket.h>  
 int bind(int sockfd, const struct sockaddr * server, socklen_t addrlen);
 返回:0---成功   -1---失敗 
 -------------------------------------------------------------------

  第一個參數是socket函數返回的套接口描述字;第二和第第三個參數分別是一個指向特定于協議的地址結構的指針和該地址結構的長度。

3、recvfrom函數:UDP使用recvfrom()函數接收數據,他類似于標準的read(),但是在recvfrom()函數中要指明目的地址。

-------------------------------------------------------------------
#include <sys/types.h>  
#include <sys/socket.h>  
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * from, size_t *addrlen);
 返回接收到數據的長度---成功   -1---失敗 
 -------------------------------------------------------------------

  前三個參數等同于函數read()的前三個參數,flags參數是傳輸控制標志。最后兩個參數類似于accept的最后兩個參數。

4、sendto函數:UDP使用sendto()函數發送數據,他類似于標準的write(),但是在sendto()函數中要指明目的地址。

-------------------------------------------------------------------
#include <sys/types.h>  
#include <sys/socket.h>  
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr * to, int addrlen);
 返回發送數據的長度---成功   -1---失敗 
 -------------------------------------------------------------------

  前三個參數等同于函數read()的前三個參數,flags參數是傳輸控制標志。參數to指明數據將發往的協議地址,他的大小由addrlen參數來指定。

server.c程序源碼:

  #include <stdio.h>                                                                                                                 
  #include <sys/socket.h>
  #include <stdlib.h>
  #include <netinet/in.h>
  #include <unistd.h>
  #include <sys/types.h>
  #include <string.h>
 
  #define _MAXLINE_ 80
  #define _SERV_PORT_  8000
  
  int main()
  {
      struct sockaddr_in server_addr,client_addr;
      socklen_t cliaddr_len;
      int sockfd;
      char buf[_MAXLINE_];
      char str[INET_ADDRSTRLEN];
      int i, n;
  
      sockfd = socket(AF_INET, SOCK_DGRAM, 0);
      if(sockfd < 0){
          printf("create socket error!...\n");
          return -1;
      }
  
      bzero(&server_addr,sizeof(server_addr));
      server_addr.sin_family = AF_INET;
      server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      server_addr.sin_port = htons(_SERV_PORT_);
  
      if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0){
          printf("bind error!...");
          close(sockfd);
          return 1;
      }
  
      printf("Accepting connections ...\n");
      while(1){
          cliaddr_len = sizeof(client_addr);
          //n = recvfrom(sockfd, buf, _MAXLINE_, 0,(struct sockaddr *)&client_addr, &cliaddr_len);
          n = recvfrom(sockfd, buf, _MAXLINE_, 0,(struct sockaddr *)&client_addr, &cliaddr_len);
          if(n == -1){
              printf("recvfrom error...\n");
              exit(1);
          }
          printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &client_addr.sin_addr, 
                  str,sizeof(str)),ntohs(client_addr.sin_port));
  
          for(i = 0; i < n; i++){
              buf[i] = toupper(buf[i]);
          }
          n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
          if(n == -1){
              printf("sendto error...\n");
          }
      }
      return 0;
  }

UDP客戶端程序設計

client.c程序源碼:

   #include <stdio.h>                                                                                                                                       
   #include <string.h>
   #include <unistd.h>
   #include <netinet/in.h>
   
   #define _MAXLINE_ 80
   #define _SERV_PORT_  8000
   
   int main(int argc, int* argv[])
  {
      struct sockaddr_in servaddr;
      int sockfd, n;
      char buf[_MAXLINE_];
      char str[INET_ADDRSTRLEN];
      socklen_t servaddr_len;
  
      sockfd = socket(AF_INET, SOCK_DGRAM, 0);

      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
      servaddr.sin_port = htons(_SERV_PORT_);
  
      while(fgets(buf, _MAXLINE_, stdin)!= NULL){
          n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)\
                  &servaddr, sizeof(servaddr));
          if(n == -1){
              printf("sendto error\n");
          }
          n = recvfrom(sockfd, buf, _MAXLINE_, 0, NULL, 0);
          if(n == -1){
              printf("recvfrom error\n");
          }
          write(STDOUT_FILENO, buf, n);
      }
  
      close(sockfd);
      return 0;
  }


運行展示,client發送小寫字母,server收到之后進行大小寫轉換,發回到client,結果如下:

基于UDP協議的網絡程序


向AI問一下細節

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

AI

上思县| 古浪县| 平塘县| 洪湖市| 潼关县| 天等县| 尚志市| 和田市| 冷水江市| 通化县| 临颍县| 耒阳市| 尤溪县| 合川市| 阿拉善盟| 新郑市| 江达县| 石河子市| 临汾市| 扶余县| 喜德县| 沾益县| 锦屏县| 合阳县| 西充县| 自治县| 南充市| 鱼台县| 甘洛县| 黄浦区| 岐山县| 莱西市| 洛阳市| 河东区| 龙门县| 东乡| 普宁市| 大宁县| 福泉市| 交城县| 南江县|