1. 程式人生 > >7.8-UC-第八課:網路通訊

7.8-UC-第八課:網路通訊

================ 第八課  網路通訊 ================
一、基本概念 ------------
1. ISO/OSI七層網路協議模型 ~~~~~~~~~~~~~~~~~~~~~~~~~~
+------------+--------------+ --- |   應用層   |  Application |  ^ +------------+--------------+  | |   表示層   | Presentation | 高層 +------------+--------------+  | |   會話層   |    Session   |  v +------------+--------------+ --- |   傳輸層   |   Transport  |  ^ +------------+--------------+  | |   網路層   |    Network   |  | +------------+--------------+ 低層 | 資料鏈路層 |   Data Link  |  | +------------+--------------+  | |   物理層   |    Physical  |  v +------------+--------------+ ---
2. TCP/IP協議族 ~~~~~~~~~~~~~~~
1) TCP (Transmission Control Protocol, 傳輸控制協議)
面向連線的服務。
2) UDP (User Datagram Protocol, 使用者資料報文協議)
面向無連線的服務。
3) IP (Internet Protocol, 網際網路協議)
資訊傳遞機制。
圖示:tcpip.bmp
3. TCP/IP協議與ISO/OSI模型的對比 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   ISO/OSI       TCP/IP +------------+------------+ |   應用層   |            | +------------+            | |   表示層   |   應用層   | TELNET/FTP/HTTP +------------+            | |   會話層   |            | +------------+------------+ |   傳輸層   |   傳輸層   | TCP/UDP +------------+------------+ |   網路層   |  網際網路層  | IP/路由 +------------+------------+ | 資料鏈路層 |            | +------------+ 網路介面層 | 驅動/裝置 |   物理層   |            | +------------+------------+
圖示:osi.bmp
4. 訊息流 ~~~~~~~~~
   ISO/OSI       TCP/IP                    TCP/IP      ISO/OSI +------------+------------+  V      ^  +------------+------------+ |   應用層   |            |  |      |  |            |   應用層   | +------------+            |  |      |  |            +------------+ |   表示層   |   應用層   |  |      |  |   應用層   |   表示層   | +------------+            |  |      |  |            +------------+ |   會話層   |            |  |      |  |            |   會話層   | +------------+------------+  |      |  +------------+------------+ |   傳輸層   |   傳輸層   |  V      ^  |   傳輸層   |   傳輸層   | +------------+------------+  |      |  +------------+------------+ |   網路層   |  網際網路層  |  |      |  |  網際網路層  |   網路層   | +------------+------------+  |      |  +------------+------------+ | 資料鏈路層 |            |  |      |  |            | 資料鏈路層 | +------------+ 網路介面層 |  |      |  | 網路介面層 +------------+ |   物理層   |            |  +      +  |            |   物理層   | +------------+------------+   \____/   +------------+------------+
5. 訊息包 ~~~~~~~~~
+-----------------+ | TELNET/FTP/HTTP | +-----------------+ |     TCP/UDP     | +-----------------+ |       IP        | +-----------------+ |     ETHERNET    | +-----------------+
從上至下,訊息包逐層遞增,從下至上,訊息包逐層遞減。
6. IP地址 ~~~~~~~~~
1) IP地址是Internet中唯一的地址標識
A. 一個IP地址佔32位,正在擴充至128位。
B. 每個Internet包必須帶IP地址。
2) 點分十進位制表示法
0x01020304 -> 1.2.3.4,高數位在左,低數位在右。
3) IP地址分級
A級:0 + 7位網路地址 + 24位本地地址 B級:10 + 14位網路地址 + 16位本地地址 C級:110 + 21位網路地址 + 8位本地地址 D級:1110 + 28位多播(Muticast)地址
4) 子網掩碼
IP地址 & 子網掩碼 = 網路地址
IP地址:  192.168.182.48 子網掩碼:255.255.255.0 網路地址:192.168.182 本地地址:48
二、套接字(Socket) ------------------
1. 介面 ~~~~~~~
   PuTTY -> telnet \  LeapFTP ->    ftp -> socket -> TCP/UDP -> IP -> 網絡卡驅動 -> 網絡卡硬體       IE ->   http /     ^                          | 應用程式 ----------------+
圖示:bsd.bmp
2. 異構 ~~~~~~~
Java @ UNIX -> socket <----> socket <- C/C++ @ Windows
3. 模式 ~~~~~~~
1) 點對點(Peer-to-Peer, P2P):一對一的通訊。
2) 客戶機/伺服器(Client/Server, C/S):一對多的通訊。
4. 繫結 ~~~~~~~
先要有一個套接字描述符,還要有物理通訊載體, 然後將二者繫結在一起。
5. 函式 ~~~~~~~ 網路通訊(通訊之間要協議) 1.通訊模型
1)建立一個socket 2)準備通訊地址 3)繫結 4)通訊 5)關閉socket 2socket函式 #include<sys/socket.h> socket(int domain,int type,int protocol); domain:域 用來選擇通訊使用的協議簇(是TCP還是其他的)

1) 建立套接字
#include <sys/socket.h>
int socket (int domain, int type, int protocol);
domain   - 域/地址族,取值:
    AF_UNIX/AF_LOCAL/AF_FILE: 本地通訊(程序間通訊);     AF_INET: 基於TCP/IPv4(32位IP地址)的網路通訊;     AF_INET6: 基於TCP/IPv6(128位IP地址)的網路通訊;     AF_PACKET: 基於底層包介面的網路通訊(核心通訊協議)。
type     - 通訊協議,取值:
    SOCK_STREAM: 資料流協議(按順序傳送),即TCP協議;     SOCK_DGRAM: 資料報協議(),即UDP協議。
protocol - 特別通訊協議,一般不用,置0即可。
成功返回套接字描述符(檔案描述符),失敗返回-1。
套接字描述符類似於檔案描述符,UNIX把網路當檔案看待, 傳送資料即寫檔案,接收資料即讀檔案,一切皆檔案。
2) 準備通訊地址(un.h)
A. 基本地址型別
struct sockaddr {     sa_family_t sa_family;   // 地址族     char        sa_data[14]; // 地址值 };
B. 本地地址型別
#include <sys/un.h>
struct sockaddr_un {     sa_family_t sun_family; // 地址族     char        sun_path[]; // 套接字檔案路徑 };
C. 網路地址型別
#include <netinet/in.h>
struct sockaddr_in {     // 地址族     sa_family_t sin_family;
    // 埠號     // unsigned short, 0-65535     // 邏輯上表示一個參與通訊的程序     // 使用時需要轉成網路位元組序     // 0-1024埠一般被系統佔用     // 如:21-FTP、23-Telnet、80-WWW     in_port_t sin_port;
    // IP地址     struct in_addr sin_addr; };
struct in_addr {     in_addr_t s_addr; };
typedef uint32_t in_addr_t;
IP地址用於定位主機,埠號用於定位主機上的程序。
3) 將套接字和通訊地址繫結在一起
#include <sys/socket.h>
int bind (int sockfd, const struct sockaddr* addr,     socklen_t addrlen);
成功返回0,失敗返回-1。
4) 建立連線
#include <sys/socket.h>
int connect (int sockfd, const struct sockaddr* addr,     socklen_t addrlen);
成功返回0,失敗返回-1。
5) 用讀寫檔案的方式通訊:read/write
6) 關閉套接字:close
7) 位元組序轉換
#include <arpa/inet.h>
// 32位無符號整數,主機位元組序 -> 網路位元組序 uint32_t htonl (uint32_t hostlong);
// 16位無符號整數,主機位元組序 -> 網路位元組序 uint16_t htons (uint16_t hostshort);
// 32位無符號整數,網路位元組序 -> 主機位元組序 uint32_t ntohl (uint32_t netlong);
// 16位無符號整數,網路位元組序 -> 主機位元組序 uint16_t ntohs (uint16_t netshort);
主機位元組序因處理器架構而異,有的採用小端位元組序, 有的採用大端位元組序。網路位元組序則固定採用大端位元組序。
8) IP地址轉換
#include <arpa/inet.h>
// 點分十進位制字串 -> 網路位元組序32位無符號整數 in_addr_t inet_addr (const char* cp);
// 點分十進位制字串 -> 網路位元組序32位無符號整數 int inet_aton (const char* cp, struct in_addr* inp);
// 網路位元組序32位無符號整數 -> 點分十進位制字串 char* inet_ntoa (struct in_addr in);
6. 程式設計 ~~~~~~~
1) 本地通訊
伺服器:建立套接字(AF_LOCAL)->準備地址(sockaddr_un)並繫結->接收資料->關閉套接字 客戶機:建立套接字(AF_LOCAL)->準備地址(sockaddr_un)並連線->傳送資料->關閉套接字
範例:locsvr.c、loccli.c
2) 網路通訊
伺服器:建立套接字(AF_INET)->準備地址(sockaddr_in)並繫結->接收資料->關閉套接字 客戶機:建立套接字(AF_INET)->準備地址(sockaddr_in)並連線->傳送資料->關閉套接字
範例:netsvr.c、netcli.c
三、基於TCP協議的客戶機/伺服器模型 ----------------------------------
1. 基本特徵 ~~~~~~~~~~~
1) 面向連線。
2) 可靠,保證資料的完整性和有序性。
ABCDEF
A ->         - B ->         | C ->         +- 時間視窗 D ->         | E -> <- A OK - F -> <- B OK      <- C OK      <- D OK      <- E OK      <- F OK
每個傳送都有應答,若在時間視窗內沒有收到A的應答, 則從A開始重發。
2. 程式設計模型 ~~~~~~~~~~~
------+-------------------------+-------------------------+------  步驟 |          伺服器         |         客戶機          | 步驟 ------+------------+------------+------------+------------+------    1  | 建立套接字 | socket     |     socket | 建立套接字 |  1    2  | 準備地址   | ...        |        ... |   準備地址 |  2    3  | 繫結套接字 | bind       |            |       ---- |    4  | 監聽套接字 | listen     |            |       ---- |    5  | 接受連線   | accept     |    connect |   建立連結 |  3    6  | 接收請求   | recv       |       send |   傳送請求 |  4    7  | 傳送響應   | send       |       recv |   接收響應 |  5    8  | 關閉套接字 | close      |      close | 關閉套接字 |  6 ------+------------+------------+------------+------------+------
圖示:handshake.bmp、tcpcs.bmp
3. 常用函式 ~~~~~~~~~~~
#include <sys/socket.h>
int listen (int sockfd, int backlog);
將sockfd引數所標識的套接字標記為被動模式, 使之可用於接受連線請求。
backlog引數表示未決連線請求佇列的最大長度, 即最多允許同時有多少個未決連線請求存在。 若伺服器端的未決連線數已達此限, 則客戶機端的connect()函式將返回-1, 且errno為ECONNREFUSED。
成功返回0,失敗返回-1。
圖示:listen.bmp
int accept (int sockfd, struct sockaddr* addr,     socklen_t* addrlen);
從sockfd引數所標識套接字的未決連線請求佇列中, 提取第一個連線請求,同時建立一個新的套接字, 用於在該連線中通訊,返回該套接字的描述符。
addr和addrlen引數用於輸出連線請求發起者的地址資訊。
成功返回通訊套接字描述符,失敗返回-1。
圖示:accept.bmp
ssize_t recv (int sockfd, void* buf, size_t len,     int flags);
通過sockfd引數所標識的套接字, 期望接收len個位元組到buf所指向的緩衝區中。
成功返回實際接收到的位元組數,失敗返回-1。
ssize_t send (int sockfd, const void* buf,     size_t len, int flags);
通過sockfd引數所標識的套接字, 從buf所指向的緩衝區中傳送len個位元組。
成功返回實際被髮送的位元組數,失敗返回-1。
圖示:concurrent.bmp
範例:tcpsvr.c、tcpcli.c
圖示:inetd.bmp
四、基於UDP協議的客戶機/伺服器模型 ----------------------------------
1. 基本特徵 ~~~~~~~~~~~
1) 無連線。
2) 不可靠,不保證資料的完整性和有序性。
         A         / \        /   \ ABC ->+-(B)-+-> CA        \   /         \ /          C
效率高速度快。
2. 程式設計模型 ~~~~~~~~~~~
------+-------------------------+-------------------------+------  步驟 |          伺服器         |         客戶機          | 步驟 ------+------------+------------+------------+------------+------    1  | 建立套接字 | socket     |     socket | 建立套接字 |  1    2  | 準備地址   | ...        |        ... |   準備地址 |  2    3  | 繫結套接字 | bind       |            |       ---- |    4  | 接收請求   | recvfrom   |     sendto |   傳送請求 |  3    5  | 傳送響應   | sendto     |   recvfrom |   接收響應 |  4    6  | 關閉套接字 | close      |      close | 關閉套接字 |  5 ------+------------+------------+------------+------------+------
圖示:udpcs.bmp
3. 常用函式 ~~~~~~~~~~~
#include <sys/socket.h>
ssize_t recvfrom (int sockfd, void* buf, size_t len,     int flags, struct sockaddr* src_addr,     socklen_t* addrlen);
通過sockfd引數所標識的套接字, 期望接收len個位元組到buf所指向的緩衝區中。
若src_addr和addrlen引數不是空指標, 則通過這兩個引數輸出源地址結構及其長度。 注意在這種情況下, addrlen引數的目標應被初始化為, src_addr引數的目標資料結構的大小。
成功返回實際接收到的位元組數,失敗返回-1。
ssize_t sendto (int sockfd, const void* buf,     size_t len, int flags,     const struct sockaddr* dest_addr,     socklen_t addrlen);
通過sockfd引數所標識的套接字, 從buf所指向的緩衝區中傳送len個位元組。
傳送目的的地址結構及其長度, 通過dest_addr和addrlen引數輸入。
成功返回實際被髮送的位元組數,失敗返回-1。
範例:udpsvr.c、udpcli.c
圖示:tcp_udp.bmp
127.0.0.1: 迴繞地址,表示本機,不依賴網路。
練習:基於TCP協議的網路銀行。
程式碼:bank/

來自為知筆記(Wiz)