要寫出基於udp的回顯伺服器我們要先了解一些預備知識如:
(ip位址有兩個版本,ipv4與ipv6在這裡我們預設ipv4)
ip位址是在
ip協議中
, 來標識 絡中不同主機的位址;對於
ipv4
來說, ip
位址是 個4位元組
, 32
位的整數
;我們通常也使
"點分 進製
" 的字串表
ip位址
, 例如
192.168.0.1 ;
點分割的每 個數字表 個位元組
, 範圍是
0 - 255;
理解源ip位址和 目的ip位址
唐僧例1;從東土大唐而來去往西天取經而去,在這個例子中東土大唐就是源ip,西天取經就是目的ip
認識埠 號
端 口號(port)是傳輸層協議的內容.
端 口號是 個2位元組
16位的整數
;端 口號 來標識一 個程序
, 告訴作業系統
, 當前的這個資料要交給哪 個程序來處理;
ip位址
+ 埠 號能夠標識 絡上的某 臺主機的某 個程序
;乙個端 號只能被 乙個程序占用 .
注意;乙個程序可以繫結多個埠號;但乙個埠號不可以繫結多個程序。
理解源埠號與目的埠號
傳輸層協議(tcp和udp)的資料段中有兩個埠號, 分別叫做源端 口號和 目的埠 號. 就是在描述 "資料是誰發的, 要發給誰」;
以上我們要先了解一些預備知識,接下來我會帶著大家繼續探索網路程式設計之基於udp的回顯伺服器,進一步的揭開網路程式設計的一角
這裡為了我們後面的學習我想為大家介紹幾個函式 1.有關網路位元組序
我們已經知道,記憶體中的多位元組資料相對於記憶體位址有大端和小端之分, 磁碟檔案中的多位元組資料相對於檔案中的偏移位址也有大端小端之分, 網路資料流同樣有大端小端之分. 那麼如何定義網路資料流的位址呢?
傳送主機通常將傳送緩衝區中的資料按記憶體位址從低到 高的順序發出
;接收主機把從 網路上接到的位元組依次儲存在接收緩衝區中
,也是按記憶體位址從低到高 的順序儲存;因此
,網路資料流的位址應這樣規定
:先發出的資料是低位址
,後發出的資料是高 位址
.tcp/ip
協議規定
,網路資料流應採 大端位元組序
,即低位址 高位元組.
所以不管這台主機是 小端機還是大 端機
, 都會按照這個
tcp/ip
規定的 網路位元組序來傳送
/接收資料
;如果當前傳送主機是小 端
, 就需要先將資料轉成 大端
; 否則就忽略
, 直接傳送即可;
為使 為了使網路程式具有可移植性,使同樣的c**在大端和小 端計算機上編譯後都能正常運 行,可以調 用以下庫函式做網 絡位元組序和主機位元組序的轉換。
這樣就解決了位元組序不統一的問題 另外
這些函式名很好記,h表 host(主機),n表 network(網路),l表 32位 整數,s表 16位短整數。例如htonl表 將32位的整數從主機位元組序轉換為 網路位元組序,例如將ip位址轉換後準備傳送。如果主機是小端位元組序,這些函式將引數做相應的 大端轉換然後返回;如果主機是大端位元組序,這些 函式不做轉換,將引數原封不動地返回。
2.socket程式設計介面socket常用api
這是udp協議常用的api。(其他的介面以後向大家介紹)
3.sockaddr結構
socket api是一 層抽象的網路程式設計介面 ,適 於各種底層網路協議,如ipv4、ipv6.然而, 各種網路協議的位址格式各不相同。有以下兩種較為常用;
如圖ipv4
和ipv6
的位址格式定義在
netinet/in.h
中,ipv4
位址 sockaddr_in
結構體表 ,包括
16位位址型別
, 16
位埠號和32位
ip位址
.ipv4
、ipv6
位址型別分別定義為常數
af_inet
、af_inet6. 這樣,
只要取得某種
sockaddr
結構體的位址
,不需要知道具體是哪種型別的
sockaddr
結構體,
就可以根據位址型別字段確定結構體中的內容.
注意socket api可以都 struct sockaddr *型別表 , 在使用的時候需要強制轉化成sockaddr_in; 這樣的好處是程式的通用性, 可以接收ipv4, ipv6, 以及unix domain socket各種型別的sockaddr結構體指標做為引數;
sockaddr結構
sockaddr_in結構
雖然socket api的接 是sockaddr, 但是我們真正在基於ipv4程式設計時, 使用的資料結構是sockaddr_in; 這個結構主要有三部分資訊: 位址型別, 埠號, ip位址.
4.位址轉換函式
本節只介紹基於ipv4的socket 絡程式設計,sockaddr_in中的成員struct in_addr sin_addr表 32位 的ip 位址但是我們通常 點分 進製的字串表 ip 位址,以下函式可以在字串表 和in_addr表 之間轉換;
字串轉in_addr的函式:
in_addr轉字串的函式:
其中inet_pton和inet_ntop不僅可以轉換ipv4的in_addr,還可以轉換ipv6的in6_addr,因此函式接 是void*addrptr,並執行緒安全,故建議大家使用。(在
apue中,
明確提出
inet_ntoa
不是執行緒安全的函式
;)好吧,我也沒有想到光介面就講了這麼多。
大家看完了嗎,開啟鏈結,我們要正式碼**了哦
Socket程式設計實踐 迭代回顯伺服器 UDP版
建立socket套接字的api 函式原型 引數說明 繫結埠號的api 函式原型 引數說明 這個函式的第二個引數在傳參的時候,我們通常是定義乙個sockaddr in型別的結構體,初始化後,強制型別轉換為sockaddr型別的。sockaddr in結構體成員說明 struct sockaddr in...
用udp實現乙個回顯伺服器
1.ip 2.埠號3.udp協議4.網路位元組序記憶體中的多位元組資料相對於記憶體位址有大端和小端之分,磁碟檔案中的多位元組資料相對於檔案中的偏 移位址也有大端小端之分,網路資料流同樣有大端小端之分 c語言庫函式 網路位元組序和主機位元組序的轉換 include uint32 t htonl uin...
基於UDP協議的伺服器 UDP伺服器建立方案
udp伺服器就是實現乙個基於udp協議的伺服器來與客戶端通訊。就是用來收發資料,進行資料處理的。與tcp伺服器不同的是不用建立連線,直接呼叫recvfrom來收包。跟tcp伺服器一樣,udp伺服器也可以通過使用 socketserver 庫很容易地被建立。先定義乙個實現 handle 特殊方法的類,...