《Linux網路開發必學教程》1_網路程式設計核心概念與模式

TianSong發表於2022-05-01
問題:如何進行網路程式設計?

網路程式設計的本質

使用作業系統提供的介面函式,使得應用程式具備收發網路資料的能力

image.png

網路介面在程式碼層面是作業系統提供的函式

  • 網路程式設計只是一系列系統函式的花式玩法

應用程式通過網路介面使用作業系統的聯網能力

  • 網路程式設計是特定領域(網路)的 C 語言程式設計

協議:為進行資料通訊而預定義的資料規則
地址:網路通訊中的用於標識裝置的整數值(“xxx.xxx.xxx.xxx” 4位元組整形值可表示,單為了更容易記憶,轉換為字串)
埠號

  • 裝置為收發資料而指定的數值,用於表示具體連線
  • 可理解為:裝置中用於網路通訊的資料通道
  • 如:一臺電腦往往只擁有一個 IP 而又有多個應用程式,此時就使用埠進行區分

角色

  • 服務端:等待連線裝置
  • 客戶端:發起連線的是惡被

image.png

ps : 一臺裝置可同時作為客戶端和服務端

網路知識充電站

網址就是 IP 地址嗎? URL 是什麼,域名又是什麼?

  • 網址不是 IP 地址,是指網路資訊資源的地址(如:具體網頁的地址),即:URL
  • 域名是 IP 地址的名別,多個域名可以指向同一個 IP 地址
  • 域名 → DNS → IP 地址

協議一定是看不懂的二進位制資料嗎?

  • 協議是一種約定,即:預先定義的規則
  • 協議可以基於文字定義,也可以基於二進位制定義
小端系統:採用小端模式(little-endian)的系統,即:資料低位元組放在記憶體低地址中
0x12345678  int 4位元組
低地址 ? |78|56|34|12| ? 高地址 
大端系統:採用大端模式(big-endian)的系統,即:資料低位元組放在記憶體高地址中
0x12345678  int 4位元組
低地址 ? |12|34|56|78| ? 高地址 
網路位元組序:網址位元組順序採用大端模式,所以,在小端系統中需要做位元組轉換

網路程式設計模式

1. 準備連線
2. 連線遠端裝置
3. 收發資料
4. 關閉麗娜姐

image.png

初探網路程式設計介面

#include <sts/types.h>
#include <sys/socket.h>

函式原型功能描述
int socket(int domain, int type, int protocal);建立套接字,為網路連線做準備
int connect(int socket, struct sockaddr *addr, socklen_t len);連線指定地址的遠端裝置
ssize_t send(int fd, const void *buf, size_t n, int flags);傳送資料到遠端裝置
ssize_t recv(int fd, void *buf, size_t n, int flags);接收遠端裝置發回的資料
int close(int fd);關閉連線,銷燬套接字

程式設計實驗:網路程式設計初體驗

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{  
   int sock = 0;
   struct sockaddr_in addr = {0};
   char *tosend = "GET /index.html HTTP/1.1\nHOST: www.dt4sw.com\nUser-Agent: TEST\nConnection: close\n\n";
   int len = 0;
   char buf[128] = {0};
   int r = 0;

   sock = socket(PF_INET, SOCK_STREAM, 0);
   if (sock == -1) {
      printf("socket error\n");
      return -1;
   }

   addr.sin_family      = AF_INET;
   addr.sin_addr.s_addr = inet_addr("47.99.217.175");
   addr.sin_port        = htons(80);

   if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
      printf("connected error\n");
      return -1;
   }

   printf("connect success\n");

   len = send(sock, tosend, strlen(tosend), 0);

   printf("send bytes = %d\n", len);

   len = 0;
   do {
      int i = 0;

      r = recv(sock, buf, sizeof(buf), 0);

      if (r > 0) {
         len += r;
      }

      for (i=0; i<r; ++i) {
         printf("%c", buf[i]);
      }
   } while (r > 0);

   printf("\n");
   printf("recv bytes = %d\n", len);

   return 0;
}

輸出:

./a.out 
connect success
send bytes = 81
HTTP/1.1 200 OK
Content-Type: text/html

......
......

  <script src="./static/js/app.js"></script>
</body>
</html>
recv bytes = 22382
思考:這次所編寫的網路程式是什麼角色?

答:客戶端

相關文章