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

7.8-UC-第八課:網絡通信

控制 tag short 提取 固定 http ++ ip地址 ipv4

================第八課 網絡通信================
一、基本概念------------
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)關閉socket2socket函數 #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)

7.8-UC-第八課:網絡通信