1.創建套接字
int socket(int domain, int type, int protocol);
第一個參數,底層用的ip報文統一使用的網絡協議都是AFIN
第二個參數,面向流的傳輸協議
SOCK_DGRAM(數據報套接字類型):支持數據報(無連接、不可靠且具有固定最大長度的消息 )
第三個參數,設置為0
創建成功返回一個文件描述符,創建失敗返回-1
2.綁定socket信息,ip和端口
2.1 填充sockaddr_in 結構體
????????IP信息和端口信息一定要發送到網絡
?????????
(1)本地格式轉化成網序列
? ?
local.sin_port = htons(_port);
將本地字節序(也叫主機字節序 )的端口號,轉換為網絡字節序(大端序 高字節存低地址,低字節存高地址),從而讓端口號能在網絡通信中正確識別和傳輸
eg:主機是小端序(如常見的 x86 架構 ),_port 的值是 8080(十進制 ),在主機內存中以小端序存儲(低字節在前 ),二進制可能表示為 0x1F 0x20(十六進制拆分 )。經過 htons 轉換后,會變成大端序的 0x20 0x1F ,然后賦值給 local.sin_port ,滿足網絡字節序要求
(2)ip也是一樣
1. ip轉化為4字節
2. 4字節轉化為網絡序列
1.點分十進制 -> 4字節二進制(主機字節序)
eg:IP 地址 192.168.1.100
192 -> 11000000
168 ->?10101000
1? ? ?->? 00000001
100 ->? 01100100
得到32位二進制? (4字節)
11000000 10101000 00000001 01100100
2. 4字節 -> 大端序
就能存到 sockaddr_in 結構體的 sin_addr.s_addr 成員里,供網絡操作使用
local.sin_addr.s_addr = inet_addr(_ip.c_str());
函數申明?in_addr_t inet_addr(const char *cp);
在實際編程中,我們不需要手動寫 in_addr_t inet_addr(const char *cp); 這個聲明,而是通過包含頭文件 #include <arpa/inet.h> 來獲取該函數的聲明
函數調用??local.sin_addr.s_addr = inet_addr(_ip.c_str());
local.sin_addr.s_addr = inet_addr("192.168.1.100");
不管是內網還是公網的客戶端,都能訪問到服務,就可以用 INADDR_ANY ,不用關心具體綁定哪個 IP
INADDR_ANY 的核心作用就是讓服務器「綁定到本機所有可用的網絡接口」,從而實現:
無論客戶端通過服務器的公網 IP、內網 IP 還是本地回環地址(127.0.0.1) 發送請求,只要端口正確,服務器都能接收到。
無需提前知道服務器有哪些 IP 地址(比如服務器可能有多個網卡,或 IP 是動態分配的),簡化配置
recvfrom 和 sendto 函數
服務器要顯示bind,ip和端口號必須是眾所周知且不能輕易改變的
1. 收消息,客戶端要給服務器發消息,為了讓服務端處理數據
recvfrom 接收數據
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,?struct sockaddr *src_addr, socklen_t *addrlen);
client的bind
client要訪問目標服務器,需要知道服務器ip和端口,而客戶端和服務器是同一家公司寫的,就能知道
客戶端需要bind即使是客戶端,發送數據時也需要一個「源端口」,讓服務器能通過 recvfrom 獲取客戶端的端口。但不要顯示地bind,首次發消息,os會自動給client進行bind,os知道ip,os隨機選擇端口號,只要端口號是唯一的就可以
(1)服務端必須「顯式綁定」
服務端需要一個固定、已知的端口(比如 80、8080),讓客戶端能主動連接。因此必須手動 bind:
(2)客戶端可以「隱式綁定」
客戶端不需要固定端口(端口由系統自動分配),因此可以省略 bind 操作。當客戶端第一次調用 sendto 或 recvfrom 時:
操作系統會自動為客戶端分配一個隨機的空閑端口(通常在 1024~65535 范圍內)
同時自動綁定客戶端的 IP(通常是本機 IP,如 192.168.1.100)
操作系統會自動完成以下步驟:
檢查客戶端套接字是否已綁定端口:
如果未綁定,進入「自動綁定流程」。
分配隨機端口:
從 1024~65535 中選一個未被占用的端口(類似臨時端口分配)。
綁定客戶端 IP:
自動綁定到客戶端的「默認出網 IP」(可能是 127.0.0.1 或本機真實 IP,由路由策略決定)