小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linux Socket編程-基礎(chǔ)知識(shí)點(diǎn)

 西北望msm66g9f 2021-08-09

套接字(Socket)按照操作類型可以分為三類:

1.流式套接字(SOCK_STREAM):面向連接的Socket,只能收發(fā) TCP 協(xié)議的數(shù)據(jù);

2.數(shù)據(jù)報(bào)式套接字(SOCK_DGRAM):面向無連接的Socket,只能收發(fā) UDP 協(xié)議的數(shù)據(jù);

3.原始套接字(SOCK_RAW)可以用來自行組裝數(shù)據(jù)包,可以接收本機(jī)網(wǎng)卡上所有的數(shù)據(jù)幀(數(shù)據(jù)包),直接操作系統(tǒng)網(wǎng)絡(luò)核心(Network Core)。

Socket基本數(shù)據(jù)結(jié)構(gòu)

1.套接字地址結(jié)構(gòu)

IPV4

A.新式機(jī)構(gòu)

<netinet/in.h>

struct sockaddr_in

{

   unsigned           short sin_len;      //IPv4地址長(zhǎng)度

   short int          sin_family;   //指代協(xié)議簇,在TCP套接字編程只能是AF_INET

   unsigned           short sin_port;     //存儲(chǔ)端口號(hào)(使用網(wǎng)絡(luò)字節(jié)順序),數(shù)據(jù)類型是一個(gè)16為的無符號(hào)整形類型

   struct   in_addr   sin_addr;//存儲(chǔ)IP地址,IP地址是一個(gè)in_add結(jié)構(gòu)體(結(jié)構(gòu)在下面)

   unsigned char      sin_zero[8];     //為了讓sockaddr與sockaddr_in兩個(gè)數(shù)據(jù)結(jié)構(gòu)保持大小相同而保留的空字節(jié)

};

struct in_addr

{

   unsigned long s_addr;   //按照網(wǎng)絡(luò)字節(jié)順序存儲(chǔ)IP地址

};

大端模式和小端模式

  1)小端就是低位字節(jié)排放在內(nèi)存的低地址端,高位字節(jié)排放在內(nèi)存的高地址端。

  2)大端就是高位字節(jié)排放在內(nèi)存的低地址端,低位字節(jié)排放在內(nèi)存的高地址端。

  舉一個(gè)例子,比如數(shù)字0x12 34 56 78在內(nèi)存中的表示形式為:

  A. 大端模式:

  低地址 -----------------> 高地址

  0x12  |  0x34  |  0x56  |  0x78

  B. 小端模式:

  低地址 ------------------> 高地址

  0x78  |  0x56  |  0x34  |  0x12

B.老式結(jié)構(gòu)

struct sockaddr

{

   unsigned short  sa_family;  //套接字的協(xié)議簇地址類型,TCP/IP協(xié)議對(duì)于IPv4地址類型為AF_INET

   char            sa_data[14];//存儲(chǔ)具體的協(xié)議地址

};

IPV6

A.新式結(jié)構(gòu)

<netinet/in.h>

struct sockaddr_in6

{

   unsigned short int       sin6_len;   //IPv6結(jié)構(gòu)長(zhǎng)度,是一個(gè)無符號(hào)的8為整數(shù),表示128為IPv6地址長(zhǎng)度

   short int                sin6_family; //地址類型AF_INET6

   unsigned short int       sin6_port;   //存儲(chǔ)端口號(hào),按網(wǎng)絡(luò)字節(jié)順序

   unsigned short int       sin6_flowinfo;  //低24位是流量標(biāo)號(hào),然后是4位的優(yōu)先級(jí)標(biāo)志,剩下四位保留

   struct in6_addr          sin6_addr;      //IPv6地址,網(wǎng)絡(luò)字節(jié)順序

};

B.老式結(jié)構(gòu)

struct in6_addr

{

    unsigned long s6_addr;  //128位的IPv6地址,網(wǎng)絡(luò)字節(jié)順序

};

常用函數(shù)

1.socket函數(shù)?

函數(shù):int socket(int, int, int);

?功能:創(chuàng)建一個(gè)套接字

?解釋:int socket(int af, int type, int protocol);

  • af:表示一個(gè)地址家族,IPv4連接時(shí)填A(yù)F_INET,IPv6連接時(shí)對(duì)應(yīng)AF_INET6

  • type:表示套接字類型,如果是SOCK_STREAM表示創(chuàng)建面向連接的流式套接字;如果是SOCK_DGRAM表示面向無連接的數(shù)據(jù)包套接字;為SOCK_RAW表示創(chuàng)建原始套接字

  • protocol:表示套接口所用的協(xié)議,如果用戶不指定,可以設(shè)置為0

  • 返回值:int類型的一個(gè)指向傳輸提供者的句柄(套接字)

socket函數(shù)的family常值

socket函數(shù)的type常值

 socket函數(shù)的protocol常值

socket函數(shù)中family和type參數(shù)的組合

2.bind函數(shù)?

函數(shù):int bind(int, const struct sockaddr *, socklen_t)?

功能:將套接字綁定到指定端口和地址上?

解釋:

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

  • sockfd:表示套接字標(biāo)識(shí)

  • my_addr:是一個(gè)指向struct sockaddr結(jié)構(gòu)體類型的指針,一般綁定 IPv4地址傳入struct sockaddr_in指針,IPv6地址傳入struct sockaddr_in6指針(PS:這里我也不是很清楚,sockaddr_in結(jié)構(gòu)體里面有地址族,改變地址族為IPv6的不知道行不行,下面的演示和注釋以前面的struct sockaddr_in結(jié)構(gòu)體為主),都包含地址和端口號(hào)信息,強(qiáng)轉(zhuǎn)成需要的類型

  • addrlen:確定my_addr緩沖區(qū)的長(zhǎng)度,就是前面結(jié)構(gòu)體的大小

  • 返回值:如果函數(shù)執(zhí)行成功,則返回值為0,失敗則為-1

3.listen函數(shù)

?函數(shù):int listen(int, int)?

功能:將套接字設(shè)置為監(jiān)聽模式,對(duì)于流式套接字,必須處入監(jiān)聽模式才能夠接收客戶端套接字的連接

?解釋:int listen(int sockfd, int backlog);

  • sockfd:表示套接字標(biāo)識(shí)

  • backlog:表示等待連接的最大隊(duì)列長(zhǎng)度。例如:如果backlog被設(shè)置為2,此時(shí)有3個(gè)客戶端同時(shí)發(fā)出連接請(qǐng)求,那么前兩個(gè)客戶端會(huì)放置在等待連接隊(duì)列中,第三個(gè)客戶端會(huì)得到錯(cuò)誤信息。

  • 返回值:成功則返回0,失敗則返回-1

4.accept函數(shù)?

函數(shù):int accept(int, struct sockaddr * __restrict, socklen_t * __restrict)?

功能:接受客戶端的連接,在流式套接字中,只有在套接字處入監(jiān)聽狀態(tài),才能接受客戶端的連接?

解釋:int accept(int sockfd, struct sockaddr *addr, int *addrlen);

  • sockfd:表示套接字標(biāo)識(shí)

  • addr:是一個(gè)sockaddr_in結(jié)構(gòu)體指針,接收連接端地址信息

  • addrlen:前面sockaddr_in結(jié)構(gòu)體地址長(zhǎng)度指針,用來接收連接端地址信息結(jié)構(gòu)體長(zhǎng)度

  • 返回值:一個(gè)新的套接字,它對(duì)應(yīng)于已經(jīng)接受的客戶端連接,對(duì)于該客戶端的所有后續(xù)操作,都應(yīng)使用這個(gè)新的套接字

5.close函數(shù)?函數(shù):int close(int)?

功能:關(guān)閉套接字

?解釋:int close(int sockfd);

6.connect函數(shù)?

函數(shù):int connect(int, const struct sockaddr *, socklen_t)?

功能:發(fā)送一個(gè)連接請(qǐng)求

解釋:int connect(int sockfd,const struct sockaddr * addr_server, int addrlen)

  • sockfd:表示一個(gè)正準(zhǔn)備連接的套接字??蛻舳诉B接套接字int socket_client

  • addr_server:存儲(chǔ)套接字要連接主機(jī)的地址信息結(jié)構(gòu)體指針

  • addrlen:前面結(jié)構(gòu)體的也就是addr_server結(jié)構(gòu)體緩沖區(qū)的長(zhǎng)度

  • 返回值:成功則返回0,失敗則返回-1

connect函數(shù)將激發(fā)TCP的三次握手過程,而且僅在連接建立成功或出錯(cuò)時(shí)才返回,其中出錯(cuò)有如下幾種情況:

1).若TCP客戶沒有收到SYN包的響應(yīng),則返回ETIMEDOUT錯(cuò)誤。如調(diào)用該函數(shù)時(shí),內(nèi)核發(fā)送一個(gè)SYN,若無響應(yīng)則等待6s后再發(fā)一個(gè),若仍無響應(yīng),則等待24s再發(fā)一個(gè),若總共等了75s后仍未收到響應(yīng)消息則返回該錯(cuò)誤(因內(nèi)核而異)。

2).若響應(yīng)時(shí)RST,表明該服務(wù)器主機(jī)在我們指定的端口上沒有進(jìn)程等待,客戶收到RST包后馬上返回ECONNREFUSED錯(cuò)誤。

3).若客戶發(fā)出的SYN在中間的路由器上引發(fā)了一個(gè)“destination unreachable”的ICMP錯(cuò)誤,則按第一種情形繼續(xù)發(fā)送SYN,若在規(guī)定的時(shí)間內(nèi)沒有收到回應(yīng),則將ICMP錯(cuò)誤作為EHOSTUNREACH或ENETUNREACH錯(cuò)誤返回。

7.recv函數(shù)

函數(shù):ssize_t recv(int, void *, size_t, int)

功能:從流式套接字中接受數(shù)據(jù),平時(shí)開發(fā)針對(duì)TCP套接字接收數(shù)據(jù)

解釋:ssize_t recv(int sockfd,  void *buff,  size_t nbytes,   int flags)

  • sockfd表示流式套接字

  • buff用來存放recv函數(shù)接收到的數(shù)據(jù)的緩沖區(qū)

  • nbytes緩沖區(qū)的長(zhǎng)度

  • flags 表示函數(shù)的調(diào)用方式,一般填0

成功時(shí)返回接收的字節(jié)數(shù)(收到EOF是返回0),失敗是返回-1

8.send函數(shù)

函數(shù):ssize_t send(int, const void *, size_t, int)

功能:在流式套接字中發(fā)送數(shù)據(jù)

解釋:ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags          //表示函數(shù)的調(diào)用方式,一般填0,具體看下面表格

            )

  • sockfd表示流式套接字

  • buff存放要發(fā)送數(shù)據(jù)的緩沖區(qū)

  • nbytes實(shí)際要改善的數(shù)據(jù)的字節(jié)數(shù)

  • int flags 表示函數(shù)的調(diào)用方式,一般填0

返回值:成功返回發(fā)送的字節(jié)數(shù),錯(cuò)誤返回-1

9.recvfrom函數(shù)

函數(shù):ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict)

功能:用于接收一個(gè)數(shù)據(jù)包,并保存源地址

解釋:

ssize_t recvfrom(int sockfd,  void * buff, size_t nbytes, int flags,  struct sockaddr * __restrict from,  socklen_t * __restrict fromLen)

  • sockfd表示準(zhǔn)備接收的套接字

  • buff指向緩沖區(qū)的指針,用來接收數(shù)據(jù)

  • nbytes表示緩沖區(qū)的長(zhǎng)度

  • flags表示調(diào)用方式,一般填0

  • __restrict from是一個(gè)指向地址結(jié)構(gòu)體的指針,用來接收發(fā)送數(shù)據(jù)方的地址信息

  • __restrict fromLen 前面結(jié)構(gòu)體長(zhǎng)度指針

返回值:如果正確接收返回接收到的字節(jié)數(shù),失敗返回-1.

10.sendto函數(shù)

函數(shù):ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t)

功能:向指定的目的地方發(fā)送數(shù)據(jù)

解釋:ssize_t sendto(int sockfd, const void * buff, size_t nbytes,  int  flags,  const struct sockaddr *  to, socklen_t  tolen)

  • sockfd表示準(zhǔn)備發(fā)送數(shù)據(jù)的套接字

  • buff指向緩沖區(qū)的指針,該緩沖區(qū)包含將要發(fā)送的數(shù)據(jù)

  • nbytes緩沖區(qū)數(shù)據(jù)長(zhǎng)度

  • flags表示調(diào)用方式,一般填0

  • to指向目標(biāo)套接字地址的結(jié)構(gòu)體指針

  • tolen前面結(jié)構(gòu)體長(zhǎng)度

成功則返回實(shí)際傳送出去的字符數(shù),失敗返回-1,錯(cuò)誤原因存于errno 中

輔助函數(shù)

1.htons() 函數(shù)ntohs()函數(shù)?

函數(shù):u_short htons(u_short hostshort)?功能:將一個(gè)16位的無符號(hào)端整形數(shù)據(jù)由主機(jī)排列方式轉(zhuǎn)換成網(wǎng)絡(luò)排列方式,所謂的網(wǎng)絡(luò)排列方式就是大端排列方式,MacOS是采用小端的存儲(chǔ)方式存儲(chǔ)數(shù)據(jù)?

使用地方:在有關(guān)主機(jī)地址和端口號(hào)結(jié)構(gòu)體中struct sockaddr_in里面,屬性in_port_t sin_port表示端口號(hào),因?yàn)槎丝谔?hào)要用網(wǎng)絡(luò)排列方式,使用該函數(shù)轉(zhuǎn)換后賦值

函數(shù): u_short ntohs(u_short netshort)?功能: 與htons()功能相反,將16位無符網(wǎng)絡(luò)排列端口轉(zhuǎn)換成主機(jī)排列方式,也就是將16位大端排列數(shù)字轉(zhuǎn)換成小端排列方式?

使用地方: 得到地址結(jié)構(gòu)體struct sockaddr_in,將里面的in_port_t sin_port轉(zhuǎn)換成我們平時(shí)看到的小端排列的端口號(hào)

2.htonl() 函數(shù)ntohl()函數(shù)

函數(shù):u_long htonl(u_long hostlong)

功能:將一個(gè)32位無符號(hào)整形由主機(jī)排列方式轉(zhuǎn)換成網(wǎng)絡(luò)排列方式,所謂的網(wǎng)絡(luò)排列方式就是大端排列方式

使用地方:在有關(guān)主機(jī)地址和端口號(hào)結(jié)構(gòu)體中struct sockaddr_in里面,結(jié)構(gòu)體屬性struct in_addr sin_addr中的in_addr_t s_addr屬性表示IP地址信息,因?yàn)镮P地址信息要用網(wǎng)絡(luò)排列方式,使用該函數(shù)轉(zhuǎn)換后賦值

函數(shù):u_long ntohl(u_long netlong)

功能:與函數(shù) htonl()功能相反,將網(wǎng)絡(luò)排列的32位無符數(shù)據(jù)轉(zhuǎn)換成主機(jī)排列,就是將32位大端排列數(shù)字轉(zhuǎn)換成小段排列數(shù)據(jù)

使用地方:得到地址結(jié)構(gòu)體struct sockaddr_in,將里面的in_addr_t s_addr轉(zhuǎn)換成我們平時(shí)看到的小端排列32位IP地址

3.inet_addr 函數(shù)

函數(shù):in_addr_t inet_addr(const char *)

功能:將存儲(chǔ)IP地址的char字符串轉(zhuǎn)換成網(wǎng)絡(luò)排列方式的32位無符號(hào)整形,跟上面htonl()函數(shù)功能一樣

使用地方:轉(zhuǎn)換的結(jié)果可直接用來給地址信息結(jié)構(gòu)體里面的IP地址賦值,因?yàn)檗D(zhuǎn)換出來的結(jié)果是網(wǎng)絡(luò)排列的

4.inet_aton 函數(shù)

函數(shù):int inet_aton(const char *, struct in_addr *);

功能:與函數(shù)inet_addr功能一樣,將char字符串IP地址轉(zhuǎn)換成網(wǎng)絡(luò)排序的無符整形,傳入struct in_addr結(jié)構(gòu)體指針,直接賦給結(jié)構(gòu)體

5.inet_pton 函數(shù)

函數(shù):int inet_pton(int, const char *, void *);

功能:與輔助函數(shù)htonl()、inet_addr()、inet_aton()的功能一樣,將char字符串IP地址轉(zhuǎn)換成網(wǎng)絡(luò)排序的無符整形,直接賦給struct in_addr結(jié)構(gòu)體指針里面,不一樣的是可以根據(jù)地址族的不同轉(zhuǎn)換IPv6還是IPv4的地址

6.inet_ntoa 函數(shù)

函數(shù):char *inet_ntoa(struct in_addr)

功能:正好與上面的函數(shù)inet_aton功能相反,需要傳入一個(gè)關(guān)于地址信息的結(jié)構(gòu)體,解析出來C字符串的IP地址

7.inet_ntop 函數(shù)

函數(shù):const char *inet_ntop(int, const void *, char *, socklen_t);

功能:跟上面函數(shù)inet_ntoa()功能相似,于函數(shù)inet_pton()功能相反,不一樣的是他可以傳入地址族,傳入AF_INET則解析出IPv4的地址,傳入AF_INET6則解析

8.getpeername 函數(shù)?

函數(shù):int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict)?功能:獲取socket套接字對(duì)方的地址信息,返回0時(shí)正常,否則錯(cuò)誤?

解釋:int getpeername(int sockfd, struct sockaddr * peerAddr, socklen_t * addrLen)

  • sockfd:表示套接字

  • peerAddr:接收地址信息結(jié)構(gòu)體,傳入結(jié)構(gòu)體指針外面申明里面賦值,獲取到的是連接對(duì)象的地址信息

  • addrLen:地址信息結(jié)構(gòu)體的長(zhǎng)度指針

  • 返回值:返回0時(shí)可以通過地址信息指針取里面的信息,<0時(shí)錯(cuò)誤

8.getsockname 函數(shù)?

函數(shù):int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict)?功能:獲取socket套接字的地址信息,返回0時(shí)正常,否則錯(cuò)誤?

解釋:int getsockname(int sockfd, struct sockaddr * addr, socklen_t *addrLen)

  • sockfd:表示套接字

  • addr:接收地址信息結(jié)構(gòu)體,傳入結(jié)構(gòu)體指針外面申明里面賦值,獲取到的是sockfd的地址信息

  • addrLen:地址信息結(jié)構(gòu)體的長(zhǎng)度指針

  • 返回值:返回0時(shí)可以通過地址信息指針取里面的信息,<0時(shí)錯(cuò)誤

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多