網路程式設計中4個重要的位址資料結構

2022-03-14 16:03:09 字數 3694 閱讀 6531

1.ipv4: struct sockaddr_in, 16個位元組

1

struct

sockaddr_in ;

12typedef uint32_t in_addr_t;

13struct

in_addr ;

2.ipv6: struct sockaddr_in6, 28個位元組

1

struct

sockaddr_in6 ;

8struct

in6_addr in6_u;

1415

#define s6_addr in6_u.u6_addr8

16#define s6_addr16 in6_u.u6_addr16

17#define s6_addr32 in6_u.u6_addr32

18 };

3.通用結構體1: struct sockaddr, 16個位元組

1

struct

sockaddr ;

4.通用結構體2: struct sockaddr_storage,128個位元組

1

/*structure large enough to hold any socket address

2(with the historical exception of af_unix). 128 bytes reserved. */3

4#if ulong_max > 0xffffffff

5# define __ss_aligntype __uint64_t

6#else

7# define __ss_aligntype __uint32_t

8#endif

9#define _ss_size 128

10#define _ss_padsize (_ss_size - (2 * sizeof (__ss_aligntype)))

1112

struct

sockaddr_storage

13;

為什麼會有通用結構體且為什麼會有兩個通用結構體呢?以下純屬個人見解。

網路通訊中涉及到很多協議,有ipv4, ipv6, ipx, x.25, ax.25......(socket函式的domain引數表示協議族)。在網路程式設計中,不管用的是什麼協議,使用的都是同一套socket api,而每個協議表示網路位址的結構體是不一樣的,如ipv4是struct sockaddr_in,ipv6是struct sockaddr_in6,所以需要將所有這些表示網路位址的結構體抽象成乙個通用的結構體,抽象之後的結構體便是struct sockaddr。(具體協議的位址結構與通用的位址結構的關係有點類似於物件導向程式設計中物件與類的關係,我沒學過物件導向程式設計,只是隱約感覺這兩者思想有點類似)

涉及到struct sockaddr的sock api有:

1

/**/

2int bind (int sockfd, struct sockaddr *my_addr, socklen_t addrlen);34

int connect(int sockfd, const

struct sockaddr *serv_addr,

5socklen_t addrlen);67

int sendto (int s, const

void *msg, size_t len, int

flags,

8const

struct sockaddr *to, socklen_t tolen);910

/**/

11int accept (int s, struct sockaddr *addr, socklen_t *addrlen);

1213

int recvfrom (int s, void *buf, size_t len, int

flags,

14struct sockaddr *from, socklen_t *fromlen);

1516

int getpeername(int s, struct sockaddr *name, socklen_t *namelen);

17int getsockname(int s, struct sockaddr *name, socklen_t *namelen);

那為什麼會出現struct sockaddr_storage這個通用結構體呢?

身為乙個通用的位址資料結構,它的大小得要是所有具體協議位址結構大小的最大值,可是sizeof(struct sockaddr) = 16, 而sizeof(struct sockaddr_in6) = 28, 顯然struct sockaddr這個通用的資料結構hold不住ipv6啊,所以struct sockaddr_storage這個新結構橫空出世了,它的大小為128位元組,應該能裝得下目前所以協議的位址結構了。

在涉及多種協議的網路程式設計中,用struct sockaddr_storage這個結構體來表示通訊位址,呼叫socket api時,需要將struct sockaddr_storage強制型別轉換為struct sockaddr,位址長度為sizeof(struct sockaddr_storage)。如:

1

struct

sockaddr_storage addr;2/*

3位址賦值4*/

5 sendto (s, *msg, len, flags, (struct sockaddr *)&addr,

sizeof(struct sockaddr_storage));

也許有人會問,為什麼不直接把api中的struct sockaddr改成struct sockaddr_storage?每次用的時候還要強制型別轉換多麻煩。

乙個api定義後,引數是不能改變的,不然老**就無法執行了。

也許還有人會問,為什麼一開始不把struct sockaddr的大小定義得大一點?

定義struct sockaddr的時候,還在ipv4時代,定義struct sockaddr的人沒有預料到未來會有ipv6的誕生,所以將struct sockaddr定義成了跟struct sockaddr_in一樣的大小。

ipv4/ipv6混合程式設計示例:

1

struct

sockaddr_storage addr;

2 memset(&addr, 0, sizeof(struct

sockaddr_storage));

3if (isipv6 ==true)410

else

1117

18 sendto(sock, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage));

網路程式設計中重要的幾個資料結構和函式

struct in addr struct sockaddr in struct in6 addr struct sockaddr in6 struct sockaddr struct sockaddr storage 這兩個是隨ipv6一起出現的新函式,支援ipv4和ipv6,函式名稱中p的意思是...

程式設計所需的3種最重要的技能 和4個步驟

程式設計所需的三種最重要的技能 注重細節,讀和寫,發現不同 第一步 確立目標 就是先選擇乙個你要理解的概念,然後拿出一張白紙,白紙的最頂端寫下這個概念。第二步 教學 設想你是乙個老師,正在向你的小白學生講解這個概念,並將講解的內容全部寫在紙上,在這個過程中你會意識到對於這個概念自己到底理解了多少,以...

MySQL程式設計中的6個重要的實用技巧

對於mysql,第一件你必須牢記的是它的每一行命令都是用分號 作為結束的,但當一行mysql被插入在php 中時,最好把後面的分號省略掉,例如 mysql query insert into tablename first name,last name values first name last ...