天天看點

一起talk C栗子吧(第一百五十九回:C語言執行個體--基于AF_INET域的資料報套接字通信)

各位看官們,大家好,上一回中咱們說的是基于AF_INET域的流套接字通信的例子,這一回咱們說的例子是:基于AF_INET域的資料報套接字通信 。閑話休提,言歸正轉。讓我們一起talk C栗子吧!

看官們,我們在上一回中一起制作了我們的第三道佳肴是:基于AF_INET域的流套接字通信。今天,我将和大家一起制作第四道佳肴:基于AF_INET域的資料報套接字通信。

  • 制作第四道佳肴的菜單:資料報套接字過程。
  • 制作第四道佳肴的食材:資料報套接字的接口,套接字屬性,套接字位址資訊。

看官們,以上的内容,我們在前面章回中都詳細介紹過,如果大家忘記的話,可以參考前面的内容,重點是第一百四十八回的内容,因為這是我們的菜單。在食材中最麻煩是套接字位址資訊,大家可以參考一百五十五回中的例子。多說無益,我們通過具體的代碼來示範 。

伺服器端的通信過程及其代碼

//1.設定伺服器端套接字的屬性:域,類型和協定;
    char * host = "localhost";  //using localhost IP address:127.0.0.1
    char * server = "1080";     //using port 1080, it must be more then 1024
    struct addrinfo hints;
    struct addrinfo *result;
    struct sockaddr_in client_address;

    memset(&hints,,sizeof(struct addrinfo));
    result = NULL;

    hints.ai_flags = AI_NUMERICSERV;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    //get address info ,it has all attribute of socket
    res = getaddrinfo(host,server,&hints,&result);
//2. 建立伺服器端套接字
    server_fd = socket(result->ai_family,result->ai_socktype,result->ai_protocol);
//3.把伺服器端的套接字和伺服器的位址綁定在一起
    res = bind(server_fd,result->ai_addr,result->ai_addrlen);
//4.通過套接字讀取資料,這裡使用的是recvfrom函數;
    addr_len = ;
    res = recvfrom(server_fd,buf,BUF_SIZE,,(struct sockaddr *)&client_address,&addr_len);
    printf("[server] receiving data (%s) from client by socket\n",buf);
//5.釋放套接字位址資訊。這裡沒有釋放套接字,因為在用戶端已經釋放并且關閉通信
    if(result->ai_next)
        freeaddrinfo(result);
           

用戶端的通信過程及其代碼

//1.設定用戶端套接字的屬性:域,類型和協定;
    char * host = "localhost";  //using localhost IP address:127.0.0.1
    char * server = "1080";     //using port 1080, it must be more then 1024
    struct addrinfo hints;
    struct addrinfo *result;

    memset(&hints,,sizeof(struct addrinfo));
    result = NULL;

    hints.ai_flags = AI_NUMERICSERV;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    //get address info ,it has all attribute of socket
    res = getaddrinfo(host,server,&hints,&result);
//2.建立用戶端套接字;
    client_fd = socket(result->ai_family,result->ai_socktype,result->ai_protocol);
//3.通過套接字發送資料,這裡我們使用的是sendto函數;
    printf("[client] sending data (%s )to server by socket  \n",buf);
    res = sendto(client_fd,buf,sizeof(buf),,result->ai_addr,result->ai_addrlen);
//4.釋放套接字,斷開用戶端與伺服器端的通信;
    if(result->ai_next)
        freeaddrinfo(result);

    res = close(client_fd);
           

看官們,以上是核心代碼,完整的代碼放到了我的資源中,大家可以點選這裡下載下傳使用。

關于上面的代碼,我做一點簡要的說明。我們首先擷取套接字位址的資訊,然後才建立套接字。這和前一回的步驟相同,基中人原因也相同,是以就不作詳細介紹了。在這裡,我們使用了getaddrinfo函數的結果,這種方法可以提高代碼的移植性。這種方法,也使用在了bind函數和sendto函數中。代碼中其它的内容和前一章回中的内容十分類似,是以就不作詳細介紹了。

我們需要把伺服器端的代碼和用戶端的代碼分别進行編譯,并且編譯成不同的可以執行檔案:

$ gcc Ex093_InetDgramSocketClient.c -o client  //編譯用戶端
$ gcc Ex093_InetDgramSocketServer.c -o server  //編譯伺服器端
           

看官們,美味佳肴做好了,我們一起來品嘗下,品嘗方法就是運作程式,下面是程式的運作結果,請大家參考:

$ ./server &            //在後面運作伺服器
[] 
$ ./client              //運作用戶端
please input less then  chars for using. 
dgram
[client] sending data (dgram )to server by socket  
[server] receiving data (dgram) from client by socket
[]+  Done                    ./server    //伺服器運作結束
           

看官們,從上面的運作結果中可以看到,用戶端通過套接字發送資料給伺服器,而伺服器通過套接字接收用戶端發來的資料,這樣用戶端和伺服器端可以通過套接字進行通信。另外,我們進行了一次通信,通信的次數可以自己控制,甚至寫成無限次也是可以的。每次通信可以看作是一個完整的通信過程,我們在通信過程中發送的資料是字元串”dgram”,大家也可以發送其它的字元串。

各位看官,關于基于AF_INET域的資料報套接字通信的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。

繼續閱讀