bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

LinuxSocket編程簡介和實現-創新互聯

在 TCP/IP 協議中,"IP地址 + TCP或UDP端口號" 可以唯一標識網絡通訊中的一個進程,"IP地址+端口號" 就稱為 socket。本文以一個簡單的 TCP 協議為例,介紹如何創建基于 TCP 協議的網絡程序。

創新互聯建站是一家專注于網站建設、網站設計與策劃設計,金水網站建設哪家好?創新互聯建站做網站,專注于網站建設十年,網設計領域的專業建站公司;建站業務涵蓋:金水等地區。金水做網站價格咨詢:028-86922220

TCP 協議通訊流程

下圖描述了 TCP 協議的通訊流程(此圖來自互聯網):

下圖則描述 TCP 建立連接的過程(此圖來自互聯網):

服務器調用 socket()、bind()、listen() 函數完成初始化后,調用 accept() 阻塞等待,處于監聽端口的狀態,客戶端調用 socket() 初始化后,調用 connect() 發出 SYN 段并阻塞等待服務器應答,服務器應答一個SYN-ACK 段,客戶端收到后從 connect() 返回,同時應答一個 ACK 段,服務器收到后從 accept() 返回。

TCP 連接建立后數據傳輸的過程:

建立連接后,TCP 協議提供全雙工的通信服務,但是一般的客戶端/服務器程序的流程是由客戶端主動發起請求,服務器被動處理請求,一問一答的方式。因此,服務器從 accept() 返回后立刻調用 read(),讀 socket 就像讀管道一樣,如果沒有數據到達就阻塞等待,這時客戶端調用 write() 發送請求給服務器,服務器收到后從 read() 返回,對客戶端的請求進行處理,在此期間客戶端調用 read() 阻塞等待服務器的應答,服務器調用 write() 將處理結果發回給客戶端,再次調用 read() 阻塞等待下一條請求,客戶端收到后從 read() 返回,發送下一條請求,如此循環下去。

下圖描述了關閉 TCP 連接的過程:

如果客戶端沒有更多的請求了,就調用 close() 關閉連接,就像寫端關閉的管道一樣,服務器的 read() 返回 0,這樣服務器就知道客戶端關閉了連接,也調用 close() 關閉連接。注意,任何一方調用 close() 后,連接的兩個傳輸方向都關閉,不能再發送數據了。如果一方調用 shutdown() 則連接處于半關閉狀態,仍可接收對方發來的數據。

在學習 socket 編程時要注意應用程序和 TCP 協議層是如何交互的:

  1. 應用程序調用某個 socket 函數時 TCP 協議層完成什么動作,比如調用 connect() 會發出 SYN 段
  2. 應用程序如何知道 TCP 協議層的狀態變化,比如從某個阻塞的 socket 函數返回就表明 TCP 協議收到了某些段,再比如 read() 返回 0 就表明收到了 FIN 段

下面通過一個簡單的 TCP 網絡程序來理解相關概念。程序分為服務器端和客戶端兩部分,它們之間通過 socket 進行通信。

服務器端程序

下面是一個非常簡單的服務器端程序,它從客戶端讀字符,然后將每個字符轉換為大寫并回送給客戶端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define MAXLINE 80
#define SERV_PORT 8000

int main(void)
{
  struct sockaddr_in servaddr, cliaddr;
  socklen_t cliaddr_len;
  int listenfd, connfd;
  char buf[MAXLINE];
  char str[INET_ADDRSTRLEN];
  int i, n;

  // socket() 打開一個網絡通訊端口,如果成功的話,
  // 就像 open() 一樣返回一個文件描述符,
  // 應用程序可以像讀寫文件一樣用 read/write 在網絡上收發數據。
  listenfd = socket(AF_INET, SOCK_STREAM, 0);

  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(SERV_PORT);
  
  // bind() 的作用是將參數 listenfd 和 servaddr 綁定在一起,
  // 使 listenfd 這個用于網絡通訊的文件描述符監聽 servaddr 所描述的地址和端口號。
  bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

  // listen() 聲明 listenfd 處于監聽狀態,
  // 并且最多允許有 20 個客戶端處于連接待狀態,如果接收到更多的連接請求就忽略。
  listen(listenfd, 20);

  printf("Accepting connections ...\n");
  while (1)
  {
    cliaddr_len = sizeof(cliaddr);
    // 典型的服務器程序可以同時服務于多個客戶端,
    // 當有客戶端發起連接時,服務器調用的 accept() 返回并接受這個連接,
    // 如果有大量的客戶端發起連接而服務器來不及處理,尚未 accept 的客戶端就處于連接等待狀態。
    connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
   
    n = read(connfd, buf, MAXLINE);
    printf("received from %s at PORT %d\n",
        inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
        ntohs(cliaddr.sin_port));
  
    for (i = 0; i < n; i++)
    {
      buf[i] = toupper(buf[i]);
    }
      
    write(connfd, buf, n);
    close(connfd);
  }
}

新聞標題:LinuxSocket編程簡介和實現-創新互聯
文章來源:http://vcdvsql.cn/article12/jjedc.html

成都網站建設公司_創新互聯,為您提供網站內鏈App開發關鍵詞優化網頁設計公司網站設計響應式網站

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

營銷型網站建設