ipv4的位址結構為sockaddr_in,ipv6為sockaddr_in6,鏈路協議sockaddr_dl,unix域為sockaddr_un,儲存為sockaddr_storage。
**套接字位址結構總是以引用形式來傳遞!
struct in_addr
;struct sockaddr_in
;
**ipv4位址和tcp,udp埠號在套接字位址結構中總是以【網路位元組序】來儲存。
struct in6_addr ;
#define sin6_len /*for test*/
struct sockaddr_in6 ;
**v4的位址族為af_inet,v6的位址族為af_inet6。
比如:
struct sockaddr_in serv;
bind(sockfd, (struct sockaddr *) &serv, sizeof(serv));
意思是,既作為函式的引數,又作為函式的一部分結果。(通過引用形式傳遞)
(2)從核心到程序的函式:accept, recvfrom, getsockname, getpeername,兩個引數分別指向某套接字的指標,指向表示該結構大小的整數變數的指標。
**網路協議使用大端位元組序來傳送。
我們把某個給定系統所用的位元組序稱為主機位元組序。
union結構:變數成員公用同一記憶體,其長度為聯合中最大的變數長度。
判斷主機位元組序:
#include
using
namespace
std;
int main()
un; short ssample = 0x0102;
un.s = ssample;
if (sizeof(un.s) == 2)
else
if (un.bytes[0] == 2 && un.bytes[1] == 1)
else
}else
return
0;}
在進行網路程式設計時,我們不需要關心機器字節序和網路位元組序到底是little-endian還是big-endian,我們只需要知道資料在當前機器上的程序處理時,需要使用本機位元組序,當資料在網路上傳遞時,需要使用網路位元組序。通過下面這四個函式,可以方便的進行本機與網路位元組序之間的轉換:
#include
uint16_t htons(uint16_t host_16_bit_value);
uint32_t htonl(uint32 _t host_32_bit_value);
//both return: value in network byte order
uint16_t ntohs(uint16_t net_16_bit_value);
uint32_t ntohl(uint32_t net_32_bit_value);
//both return: value in host byte order
h代表host, n代表network;
s代表short,l代表long。
(s視為乙個16位的值比如埠號,l視為乙個32位的值比如ipv4位址)
unix下有兩組位元組操作函式,一組以b(byte)開頭,是socket庫提供的自己操作函式,一種以mem(memory)開頭,由ansi c提供。
#include // 注意這裡不是,多了乙個s
void bzero(void* dest, size_t nbyte);
void bcopy(const
void* src, void* dest, size_t nbyte);
int bcmp(const
void* ptr1,void* ptr2, size_t nbyte);
我們通常使用bzero而不是memset,因為bzero只有兩個引數!
這幾個函式都是用於點分十進位制ip和網路位元組序二進位制ip相互轉換。
#include
/** 注意:
* 1 下面一對函式,相互轉換,a代表字串,n代表網路位元組序
* 2 沒有長度引數,因為點分十進位制額字串長度比較固定,程式可以分析
* 3 inet_ntoa接收的引數是值,而不是指標,比較少見,而且返回的值是在靜態內容中,
* 且執行修改,因為不是const
* 4 inet_aton 返回1代表成功轉換,0代表失敗,可以理解為true和false,
* 與一般的0標識成功有點不同
*/int inet_aton(const
char* strptr, struct in_addr* addrptr);
char* inet_ntoa(struct in_addr inaddr);
/** 注意:
* 此方法過時,因為文件不全,更主要的是對於「255.255.255.255」轉換得到結果與錯誤碼相同,有缺陷,所以不建議使用。雖然使用起來,比inet_aton方便,但是隱患較多,所以最好不要使用。
*/in_addr_t inet_addr(const
char* strptr);
這一對函式與inet_aton/inet_ntoa類似,但是支援ipv6,新增了乙個family引數接受af_inet對應ipv4,af_inet6對應ipv6。」p」和」n」分別代表presentation和numeric。inet_pton/inet_ntop的函式介面更為一致。我們應在程式中使用它們。
#include
int inet_pton(int family, const
char *strptr, struct in_addr *addrptr);
const
char *inet_ntop(int family, const
void *addrptr, char *strptr, size_t len); // error, return null
// addrptr是數值格式指標,strptr是表達格式位址,如果成功返回strptr,如果失敗返回null
//**inet_ntop的strptr引數不可以是空指標,呼叫者應該為目標儲存單元分配記憶體並指定其大小
位元組流套接字上呼叫read和write獲得的位元組數可能比請求的數量少(因為核心中用於套接字的緩衝區可能滿了),此時需要我們多次呼叫read和write函式。
因此,我們使用readn,writen來代替,從而避免讓呼叫者來處理不足的位元組計數值。
readline函式每次讀取一行。
慢速版本:每讀乙個位元組呼叫一次read。
快速版本:提供緩衝,用my_read代替read,my_read每次最多讀maxline個字元,然後每次返回乙個字元。
網路程式設計第三章 套接字程式設計簡介
include unp.h struct in addr struct sockaddr in tcp或者埠總是以網路位元組序來儲存 套接字位址結構僅僅在給定主機上使用,雖然某些字段用於通訊,但是結構本身並不用於通訊 通用套接字位址結構 作為引數傳遞任何套接字函式的時候,套接字總是以引用的方式傳遞,...
unix 網路程式設計 第三章
包裹函式 就是對有錯誤返回值的函式的封裝。在unix網路程式設計中用大寫表示。err sys 必須要errno 的值才能輸出錯誤?執行緒函式遇到錯誤的時候 不設定errno的值,而是把error的值作為函式的返回值。必須檢查某個確定的錯誤,並處理它,而不是終止程序執行。unix errno 值 每當...
UNP 第三章,套接字程式設計介紹
1.套接字結構 多數套接字函式都有套接字結構引數,每個協議族都定義了自己的套接字結構,以 sockaddr 開始,並對應協議族的唯一字尾。struct sockaddr in 對應用層程式設計而言,重要的只有 sin family,sin addr,sin port 2.位元組序 網路位元組序為大端...