7.8-UC-第八課:網路通訊
阿新 • • 發佈:2018-11-29
================
第八課 網路通訊
================
一、基本概念 ------------
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)
一、基本概念 ------------
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) 建立套接字
#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/