struct sockaddr和struct sockaddr_i:
struct sockaddr和struct sockaddr_in這兩個結構體用來儲存乙個套接字的資訊。
在各種系統呼叫或者函式中,只要和網路位址打交道,就得用到這兩個結構體。
1 位址型別: ipv4還是ipv6
2 ip位址
3 埠
函式原型:
struct sockaddr
;
struct sockaddr_in
;
這兩個結構體一樣大,都是16個位元組,而且都有family屬性,不同的是:
sockaddr用其餘14個位元組來表示sa_data,而sockaddr_in把14個位元組拆分成sin_port, sin_addr和sin_zero
分別表示埠、ip位址。sin_zero用來填充位元組使sockaddr_in和sockaddr保持一樣大小。
sockaddr和sockaddr_in包含的資料都是一樣的,但他們在使用上有區別:
程式設計師不應操作sockaddr,sockaddr是給作業系統用的
程式設計師把型別、ip位址、埠填充sockaddr_in結構體,然後強制轉換成sockaddr,作為引數傳遞給系統呼叫函式
用法事例:
1
int sockfd;
2struct sockaddr_in servaddr;
34 sockfd = socket(af_inet, sock_stream, 0); 56
/* 填充struct sockaddr_in */
7 bzero(&servaddr, sizeof(servaddr));
8 servaddr.sin_family = af_inet;
9 servaddr.sin_port = htons(serv_port);
10 inet_pton(af_inet, "127.0.0.1", &servaddr.sin_addr);
1112
/* 強制轉換成struct sockaddr */
13 connect(sockfd, (struct sockaddr *) &servaddr, sizeo
將網路位址轉換成長整型
long inet_addr(char *cp); //cp表示乙個ip位址字串;
char *inet_ntoa(struct in_addr in);
建立套接字函式:
int socket(int domain,int
type,int protocol);
//引數domain用於指定建立套接字所使用的協議族(可取af_unix,af_inet,af_inte6)
//引數type指定套接字的型別(可取sock_stream,sock_dgram,sock_raw)
//引數protocol通常設定為0
int connect(int sockfd,const
struct sockaddr *serv_addr,socklen_t addrlen);
//引數sockfd是乙個由函式socket建立的套接字
//引數serv_addr是乙個位址結構,指定伺服器的ip位址和埠號
//引數addrlen為引數serv_addr的長度
將乙個套接字和某個埠繫結在一起的函式:
int bind(int sockfd,struct sockaddr *my_addr,socklen_t addrlen);
//一般只有伺服器端的程式呼叫,引數my_addr指定了sockfd將繫結到的本地位址,可以將引數my_addr的sin_addr設定為inaddr_any而不是某個確定ip位址就可以繫結到任何網路介面。
把套接字轉化為被動監聽函式:
int listen(int s,int backlog);
//引數s為套接字,引數backlog指定鏈結請求佇列的最大長度;
接收連線請求函式:
int
accept(int
s,struct sockaddr *addr,socklen_t *addrlen);
//引數s是由函式socket建立,經函式bind繫結到本地某一埠上,然後通過函式listen轉化而來的監聽套接字
//引數addr用來儲存發起連線請求的主機的位址和埠
//引數addrlen是addr所指向的結構體的大小
在tcp套接字上傳送資料函式:
ssize_t send(int s,const
void *msg,size_t len,int flags);
//函式只能對處於連線狀態的套接字使用,引數s為已建立好連線的套接字描述符,即accept函式的返回值
//引數msg指向存放待傳送資料的緩衝區
//引數len為待傳送資料的長度,引數flags為控制選項,一般設定為0
在tcp套接字上接收資料函式:
ssize_t recv(int s,void *buf,size_t len,int flags);
//函式recv從引數s所指定的套接字描述符(必須是面向連線的套接字)上接收資料並儲存到引數buf所指定的緩衝區
//引數len則為緩衝區長度,引數flags為控制選項,一般設定為0
在ucp套接字上傳送資料函式:
ssize_t sendto(int s,const
void *msg,size_t len,int flags,const
struct sockaddr *to,socklen_t tolen);
//函式功能與函式send類似,但函式sendto不需要套接字處於連線狀態,所以該函式通常用來傳送udp資料,同時因為是無連線的套接字,在使用sendto時需要指定資料的目的位址,引數msg指向待傳送資料的緩衝區。
//引數len指定了待傳送資料的長度
//引數flags是控制選項,含義與send函式中的一致
//引數to用於指定目的位址,目的位址的長度由tolen指定
在udp套接字上接收資料函式:
ssize_t recvfrom(int s ,void *buf,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen);
//與函式recv功能類似,只是函式recv只能用於面向連線的套接字,而函式recvfrom沒有此限制,可以用於從無連線的套接字上接收資料
//引數buf指向接收緩衝區
//引數len指定了緩衝區的大小
//引數flags是控制選項,含義與recv中的一致
//如果引數from非空,且該套接字不是面向連線的,則函式recvfrom返回時,引數from中將儲存資料的源位址
//引數fromlen在呼叫recvfrom前為引數from的長度,呼叫recvfrom後將儲存from的實際大小
關閉套接字函式:
int
close(int fd);
//引數fd為乙個套接字描述符;
多路復用函式:
int
select(int n,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);
//引數n是需要監視的檔案描述符數
//引數readfds指定需要監視的可讀檔案描述符集合
//引數writefds指定需要監視的可寫檔案描述符集合
//引數exceptfds指定需要監視的異常檔案描述符的集合
//引數timeout指定了阻塞的時間
網路程式設計常用結構與函式
include in.h struct in addr struct sockaddr in 用於宣告將套接字位址結構作為乙個引數傳遞進任何套接字函式時所傳遞的指標的資料型別 對於開發者而言,這些通用套接字位址結構的唯一用途是 對指向特定於協議的套接字位址 結構的指標執行型別強制轉換 include...
函式式程式設計中常用的函式(總結)
1.函式式程式設計的含義 函式式程式設計是一種程式設計的基本風格,就是構建程式的結構和元素的方式。函式式程式設計將計算過程看做是數學函式,也就是可以使用表示式程式設計。在函式的 中,函式的返回值只以來傳入函式的引數,因此使用相同的引數呼叫2次就會得到相同的結果。如果說這段話很難理解,我覺得可以這麼想...
Python「函式式程式設計」中常用的函式
1.map func,seq seq,對序列中的每個元素應用函式,python2中map 返回的是列表,python3中返回的是迭代器,可以用list 轉換成列表。以下例子為python3 python2中返回其函式為真的元素列表,python3中返回的是迭代器,可以用list 轉換成列表。以下是p...