1. 程式人生 > >實現本地主機與阿里雲伺服器的UDP通訊

實現本地主機與阿里雲伺服器的UDP通訊

0、概述

  感謝 CSDN 贈送的阿里雲免費套餐半年使用權,讓我有機會與阿里雲來個親密接觸。本文是關於如何開通雲伺服器 ECS、如何登入及使用 ECS,以及通過簡單的 UDP 通訊實現本地主機與阿里雲伺服器的連線。

這裡寫圖片描述

  阿里雲有很多種產品,主要的幾種產品介紹如下:

  • ECS (Elastic Compute Service):以虛擬機器的方式將一臺物理機分成多臺雲伺服器,提供可伸縮的計算服務。
  • SLB (Server Load Balance):基於LVS和Tengine實現的4層和7層負載均衡,有動態擴容,session保持等特點。
  • RDS (Relational Database Service);:通過雲服務的方式讓關係型資料庫管理、操作和擴充套件變得更加簡單。
  • OCS (Open Cache Service):基於內部Tair,增加一層Proxy,支援海量小資料的高速訪問。
  • OTS(Open Table Service):海量(結構化)資料儲存和實時查詢服務。
  • OSS(Open Store Service):對任意大小資料物件提供高可用,高可靠的海量儲存服務。
  • CDN(Content Delevery Network):通過覆蓋全網的快取服務以及負載均衡等技術將使用者請求定向到最合適的區域,提高使用者服務的響應速度及網站服務能力。
  • OAS (Open Archive Service):離線歸檔,冷資料備份,類似Amazon Glacier。
  • ODPS(Open Data Processing Service):海量資料處理和分析平臺。
  • SLS (Simple Log Service):解決異構、分散式系統中日誌實時收集、儲存與查詢的基礎服務。

1、開通雲伺服器 ECS

  開通雲伺服器 ECS 的步驟很簡單,進入阿里雲官網(https://www.aliyun.com/),找到“產品與服務” –> “雲端計算基礎服務” –> “彈性計算” –> “雲伺服器 ECS”。點選進入購買頁面,根據實際應用需求進行配置,具體可以參考:https://yq.aliyun.com/edu/lesson/play/498 。由於我的是免費體驗套餐,可選項較少,因此很快就完成開通了。
  

這裡寫圖片描述

  我這裡選擇的是映象是 Ubuntu 16.04 64bit,完成 ECS 的開通後就可以進入管理後臺。可以看到,分配的公網 IP 為 120.77.200.26,之後我們就可以通過這個公網 IP 進行登入以及網路訪問了。

這裡寫圖片描述

2、登入及使用 ECS

  我們可以在本地 Ubuntu 中通過 SSH 登入到雲伺服器 ECS,執行如下命令:

$ ssh root@120.77.200.26

  輸入雲伺服器的 root 賬戶密碼即可登入,如下:

這裡寫圖片描述

  我們可以簡單檢視一些雲伺服器 ECS 的資訊,如 uname -a 檢視核心版本:

這裡寫圖片描述

  用 df -h 檢視磁碟空間:

這裡寫圖片描述

  用 fdisk -l 檢視硬碟及其引數資訊:

這裡寫圖片描述

  在這裡我們發現 /dev/vda1 可用,而 /dev/vdb 的 20GB 磁碟分割槽還沒有掛載,我們去阿里雲管理後臺檢視,確實存在一塊 20GB 的高效雲盤。所以我們需要將它掛載,以便使用。

這裡寫圖片描述

  執行 fdisk /dev/vdb 進行磁碟分割槽及格式化操作。輸入“n”新建一個分割槽,Partition type 選擇“p”,Partition number 選擇“1”,First sector 和 Last sector 選擇預設即可,之後輸入“wq”儲存退出。整個過程如下:

這裡寫圖片描述

  用 fdisk -l 檢查一下,可以看到比剛才多了 /dev/vdb1 一項。

這裡寫圖片描述

  然後進行對磁碟進行格式化,執行命令 mkfs.ext3 /dev/vdb1 ,稍等一會即格式化完畢,如下:

這裡寫圖片描述

  然後掛載磁碟,執行如下命令:

$ echo /dev/vdb1 /mnt ext3 default 0 0 >> /etc/fstab

  執行 cat /etc/fstab 檢查是否寫成功。然而此時掛載並沒有生效,所以我們還需要手動掛載一下,命令如下:

$ mount /dev/vdb1 /mnt

  之後再次用 df -h 檢視,可以看到 /dev/vdb1 已經掛載成功,掛載點正是 /mnt 目錄,如下:

這裡寫圖片描述

3、實現 UDP 通訊

  我們在雲伺服器 ECS 作為 UDP 通訊的 Server,本地主機作為 Client。程式碼如下:

【服務端 server.c】

// 標頭檔案省略

char rbuf[50];    

int main()    
{    
    int sockfd;    
    int size;    
    int ret;    
    int on =1;    
    struct sockaddr_in saddr;    
    struct sockaddr_in raddr;    

    // 設定地址資訊,ip資訊    
    size = sizeof(struct sockaddr_in);    
    bzero(&saddr, size);    
    saddr.sin_family = AF_INET;    
    saddr.sin_port = htons(8888);  // 繫結的埠號,1024以下不要用
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);    

    // 建立udp 的套接字    
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);    
    if(sockfd<0)    
    {    
        perror("socket failed");    
        return -1;    
    }    

    // 設定埠複用    
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));     

    // 繫結地址資訊,ip資訊    
    ret = bind(sockfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr));    
    if(ret<0)    
    {    
        perror("sbind failed");    
        return -1;    
    }    

    int val = sizeof(struct sockaddr);    
    // 迴圈接收客戶端發來的訊息    
    while(1)    
    {    
        puts("waiting data ......");    
        ret=recvfrom(sockfd, rbuf, 50, 0, (struct sockaddr*)&raddr, &val);    
        if(ret <0)    
        {    
            perror("recvfrom failed");    
        }    

        printf("the data :%s\n", rbuf);    
        bzero(rbuf, 50);    
    }    

    close(sockfd);    
    return 0;    
}    

【客戶端 client.c】

// 標頭檔案省略 

char wbuf[50];    

int main()    
{    
    int sockfd;    
    int size,on = 1;    
    struct sockaddr_in saddr;    
    int ret;    

    size = sizeof(struct sockaddr_in);    
    bzero(&saddr, size);    

    // 設定地址資訊,ip資訊    
    saddr.sin_family = AF_INET;    
    saddr.sin_port = htons(8888);  // 埠要和服務端繫結的一樣  
    saddr.sin_addr.s_addr = inet_addr("120.77.200.26");// 120.77.200.26 為雲伺服器的公網ip,這個很重要!   

    // 建立udp 的套接字    
    sockfd= socket(AF_INET, SOCK_DGRAM,0);    
    if(sockfd<0)    
    {    
        perror("failed socket");    
        return -1;    
    }    
    // 設定埠複用    
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));    

    // 迴圈傳送資訊給服務端    
    while(1)    
    {    
        puts("please enter data:");    
        gets(wbuf);    
        ret=sendto(sockfd, wbuf, 50, 0, (struct sockaddr*)&saddr, sizeof(struct sockaddr));    
        if(ret<0)    
        {    
            perror("sendto failed");    
        }    

        bzero(wbuf, 50);    
    }    
    close(sockfd);    
    return 0;    
}    

  分別在雲伺服器和本地主機上編譯 server.c 和 client.c,執行效果如下:

【本地主機】

這裡寫圖片描述

【雲伺服器】

這裡寫圖片描述