网络编程套接字API
?
int inet_pton(int family, const char *strptr, void *addrptr);分析:
- 第一個(gè)參數(shù)可以是AF_INET或AF_INET6:
- 第二個(gè)參數(shù)是一個(gè)指向點(diǎn)分十進(jìn)制串的指針:
- 第三個(gè)參數(shù)是一個(gè)指向轉(zhuǎn)換后的網(wǎng)絡(luò)字節(jié)序的二進(jìn)制值的指針。
?
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);分析:
- 第一個(gè)參數(shù)可以是AF_INET或AF_INET6:
- 第二個(gè)參數(shù)是一個(gè)指向網(wǎng)絡(luò)字節(jié)序的二進(jìn)制值的指針;
- 第三個(gè)參數(shù)是一個(gè)指向轉(zhuǎn)換后的點(diǎn)分十進(jìn)制串的指針;
- 第四個(gè)參數(shù)是目標(biāo)的大小,以免函數(shù)溢出其調(diào)用者的緩沖區(qū)
?
strcut sockaddr 很多網(wǎng)絡(luò)編程函數(shù)誕生早于IPv4協(xié)議,那時(shí)候都使用的是sockaddr結(jié)構(gòu)體,為了向前兼容,現(xiàn)在sockaddr退化成了(void *)的作用,傳遞一個(gè)地址給函數(shù),至于這個(gè)函數(shù)是sockaddr_in還是sockaddr_in6,由地址族確定,然后函數(shù)內(nèi)部再?gòu)?qiáng)制類(lèi)型轉(zhuǎn)化為所需的地址類(lèi)型。
?1. socketaddr_in結(jié)構(gòu)體:
struct sockaddr_in {sa_family_t sin_family; /* address family: AF_INET */in_port_t sin_port; /* port in network byte order */struct in_addr sin_addr; /* internet address */ };struct in_addr {uint32_t s_addr; /* address in network byte order */ };套接字api
?1. socket函數(shù)原型:
int socket(int domain, int type, int protocol);分析:
-
成功:返回指向新創(chuàng)建的socket的文件描述符,失敗:返回-1,設(shè)置errno
分析:
- sockfd:socket文件描述符
- addr:構(gòu)造出IP地址加端口號(hào)
- addrlen:sizeof(addr)長(zhǎng)度
- 返回值:功返回0,失敗返回-1, 設(shè)置errno
?【注意】:服務(wù)器程序所監(jiān)聽(tīng)的網(wǎng)絡(luò)地址和端口號(hào)通常是固定不變的,客戶(hù)端程序得知服務(wù)器程序的地址和端口號(hào)后就可以向服務(wù)器發(fā)起連接,因此服務(wù)器需要調(diào)用bind綁定一個(gè)固定的網(wǎng)絡(luò)地址和端口號(hào)。bind()的作用是將參數(shù)sockfd和addr綁定在一起,使sockfd這個(gè)用于網(wǎng)絡(luò)通訊的文件描述符監(jiān)聽(tīng)addr所描述的地址和端口號(hào)。前面講過(guò),struct sockaddr *是一個(gè)通用指針類(lèi)型,addr參數(shù)實(shí)際上可以接受多種協(xié)議的sockaddr結(jié)構(gòu)體,而它們的長(zhǎng)度各不相同,所以需要第三個(gè)參數(shù)addrlen指定結(jié)構(gòu)體的長(zhǎng)度。如:
struct sockaddr_in servaddr; bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(6666);?首先將整個(gè)結(jié)構(gòu)體清零,然后設(shè)置地址類(lèi)型為AF_INET,網(wǎng)絡(luò)地址為INADDR_ANY,這個(gè)宏表示本地的任意IP地址,因?yàn)榉?wù)器可能有多個(gè)網(wǎng)卡,每個(gè)網(wǎng)卡也可能綁定多個(gè)IP地址,這樣設(shè)置可以在所有的IP地址上監(jiān)聽(tīng),直到與某個(gè)客戶(hù)端建立了連接時(shí)才確定下來(lái)到底用哪個(gè)IP地址,端口號(hào)為6666
int listen(int sockfd, int backlog);- sockfd:socket文件描述符
- backlog:排隊(duì)建立3次握手隊(duì)列和剛剛建立3次握手隊(duì)列的鏈接數(shù)和
【注意】:典型的服務(wù)器程序可以同時(shí)服務(wù)于多個(gè)客戶(hù)端,當(dāng)有客戶(hù)端發(fā)起連接時(shí),服務(wù)器調(diào)用的accept()返回并接受這個(gè)連接,如果有大量的客戶(hù)端發(fā)起連接而服務(wù)器來(lái)不及處理,尚未accept的客戶(hù)端就處于連接等待狀態(tài),listen()聲明sockfd處于監(jiān)聽(tīng)狀態(tài),并且最多允許有backlog個(gè)客戶(hù)端處于連接待狀態(tài),如果接收到更多的連接請(qǐng)求就忽略。listen()成功返回0,失敗返回-1。
?
?
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);函數(shù)原型:?
- sockdf:socket文件描述符
- addr:傳出參數(shù),返回鏈接客戶(hù)端地址信息,含IP地址和端口號(hào)
- addrlen:傳入傳出參數(shù)(值-結(jié)果),傳入sizeof(addr)大小,函數(shù)返回時(shí)返回真正接收到地址結(jié)構(gòu)體的大小
- 返回值:成功返回一個(gè)新的socket文件描述符,用于和客戶(hù)端通信,失敗返回-1,設(shè)置errno
?分析:
- sockdf:socket文件描述符
- addr:傳入?yún)?shù),指定服務(wù)器端地址信息,含IP地址和端口號(hào)
- addrlen:傳入?yún)?shù),傳入sizeof(addr)大小
- 返回值:成功返回0,失敗返回-1,設(shè)置errno
【注意】:客戶(hù)端需要調(diào)用connect()連接服務(wù)器,connect和bind的參數(shù)形式一致,區(qū)別在于bind的參數(shù)是自己的地址,而connect的參數(shù)是對(duì)方的地址。connect()成功返回0,出錯(cuò)返回-1。
總結(jié)
以上是生活随笔為你收集整理的网络编程套接字API的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Leetcode 7. 整数反转
- 下一篇: 家在洹上剧情介绍