linux函數(shù)

socket();創(chuàng)建一個套接字


當前正在學習的網(wǎng)絡(luò)編程是基于linux系統(tǒng)的C++網(wǎng)絡(luò)編程,上面是在linux下的socket定義

輸入:

domain:翻譯為域,這里就是制定為套接字選擇的地址協(xié)議,常見的有IPV4、IPV6等

AF_INET IPv4 Internet protocols

AF_INET6 IPv6 Internet protocols

AF_UNIX Local communication

(linux翻譯)domain參數(shù)指定通信域;這將選擇用于通信的協(xié)議族。

type:創(chuàng)建套接字選擇的數(shù)據(jù)傳輸協(xié)議,常見的有SOCK_STREAM數(shù)據(jù)流協(xié)議、SOCK_DGRAM數(shù)據(jù)報協(xié)議,一種是基于TCP協(xié)議,一種基于UDP協(xié)議


(linux)套接字具有指定的類型,該類型指定通信語義。當前定義的類型有:

SOCK_STREAM提供有序的、可靠的、雙向的、基于連接的字節(jié)流。帶外數(shù)據(jù)傳輸機制可以被支持。

SOCK_DGRAM支持數(shù)據(jù)報(無連接,固定最大長度的不可靠消息)。

protocol:協(xié)議類型,這個我也說不太清楚,一般默認為0即可

(linux)協(xié)議指定套接字要使用的特定協(xié)議。通常只存在一個單獨的協(xié)議來支持一個部分

指定協(xié)議族中的Ular套接字類型,在這種情況下,protocol可以指定為0。然而,有可能很多

協(xié)議可能存在,在這種情況下,必須以這種方式指定特定的協(xié)議。使用的協(xié)議號是特定的

“交流領(lǐng)域”,交流將在其中發(fā)生;看到協(xié)議(5)。如何映射協(xié)議名請參見getprotoent(3)

協(xié)議號的字符串。

返回值:等下來補充

示例:

#include <sys/types.h> /* See NOTES */

?#include <sys/socket.h>

socket(AF_INET,SOCK_STREAM,0);


bind();給套接字綁定一個名稱,根據(jù)里面要傳遞的參數(shù),其實就是給套接字綁定一個地址,這里后面等下會具體來說

struct sockaddr{

sa_family_t sa_family;

char sa_data[14];

};


sockfd:socket函數(shù)的返回值

const struct sockaddr *addr:要說起這個函數(shù),可能需要提到一個概念性的問題。


上面是sockaddr的結(jié)構(gòu),因此為了傳入有效的參數(shù),我們需要去給參數(shù)進行賦值。

struce sockaddr_in addr;//初始化sockaddr,其實就是將sockaddr_in的結(jié)構(gòu)用于sockaddr,具體原因我后面也會補充

addr.sin_family=AF_INET;

addr.sin_port=htons(8888);

addr.sin_addr.s_addr=htonl(INADDR_ANY);//默認寫法

addr:&addr

addrlen:地址結(jié)構(gòu)的大小,sizeof(addr)

這里時間不是很夠,后面我會根據(jù)我的理解給出上面一些參數(shù)的原因,總的來說,參數(shù)的選擇是跟套接字創(chuàng)建的時候的參數(shù)某種程度上面保持了一致性。

Linux:

下面是linux系統(tǒng)中,在創(chuàng)建套接字的過程中,使用了AF_UNIX,所以my_addr.sun_family = AF_UNIX;我的理解是這些部分是有一些聯(lián)系的,而且在使用AF_UNIX之后,并不需要使用sockaddr_in

暫時說說我的理解(還沒有去證實)sockaddr_in,用于IPV4通信

sockaddr_in6很顯然,用于IPV6的通信

(一些其他的觀點等待去驗證)

sfd = socket(AF_UNIX, SOCK_STREAM, 0);

struct sockaddr_un my_addr, peer_addr;

my_addr.sun_family = AF_UNIX;

if (bind(sfd, (struct sockaddr *) &my_addr,

? ? ? ? ? ? ? ? ? sizeof(my_addr)) == -1)

? ? ? ? ? ? ? handle_error("bind");


返回值:On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

成功返回0,不成功返回-1,如果有錯誤就返回錯誤

示例:

struct sockaddr_in addr;

addr.sin_family=AF_INET;

addr.sin_port=htonl(8888)

addr.sin_addr.s_addr=htonl(INADDR_ANY)

int sfd;

sfd=socket(.......);

bind(sfd,(struct sockaddr*)&addr,sizeof(addr);


listen();listen - listen for connections on a socket,設(shè)置與套接字連接的服務(wù)器的上限數(shù)值(同時與服務(wù)器進行3次握手的客戶端數(shù)量)


sockfd:sockfd參數(shù)是一個文件描述符,引用SOCK_STREAM或SOCK_SEQPACKET類型的套接字。

這里的sockfd與bind()函數(shù)中的sockfd相同,都是socket();函數(shù)的返回值

backlog:backlog參數(shù)定義了sockfd的掛起連接隊列可以增長到的最大長度。上限數(shù)值,最大128

返回值:On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

成功返回0

示例:


int cfd;

struct sockaddr_in addr;

addr.sin_famliy=AF_INET;

addr.sin_port=htonl(8888);

addr.sin_addr.s_addr=htonl(INADDR_ANY);

cdf=socket(AF_INET,SOCK_STREAM,0);





accept(); accept a connection on a socket 阻塞客戶端建立連接,成功的話,返回一個與客戶端成功建立連接的套接字

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

accept()系統(tǒng)調(diào)用用于基于連接的套接字類型(SOCK_STREAM, SOCK_SEQPACKET)。它提取掛起連接隊列上的第一個連接請求。監(jiān)聽套接字sockfd創(chuàng)建一個新的已連接套接字,并返回一個引用該套接字的新文件描述符。創(chuàng)建的套接字不在監(jiān)聽狀態(tài)。原始套接字sockfd不受此調(diào)用的影響。參數(shù)sockfd是一個用socket(2)創(chuàng)建的套接字,用bind(2)綁定到本地地址,在listen(2)之后監(jiān)聽連接。

sockfd:套接字的返回值,準確的來說是服務(wù)器端通過調(diào)用正確調(diào)用socket -> bind -> listen 函數(shù)之后的用于指向存放多個客戶端緩沖隊列緩沖區(qū)的套接字描述符

*addr:是用來保存客戶端套接字對應(yīng)的內(nèi)存空間變量(包括客戶端IP和端口信息等)

*addrlen:第二個參數(shù)的大小

addr是一個傳出參數(shù),

示例:



connect();在一個套接字上面創(chuàng)建連接

connect()系統(tǒng)調(diào)用將文件描述符sockfd引用的套接字連接到由addr指定的地址。參數(shù)addrlen指定了addr的大小。addr中的地址格式由套接字sockfd的地址空間決定;詳見socket(2)。如果套接字sockfd類型為SOCK_DGRAM,則addr是缺省情況下發(fā)送數(shù)據(jù)報的地址,也是接收數(shù)據(jù)報的唯一地址。如果socket類型為SOCK_STREAM或SOCK_SEQPACKET,則該調(diào)用嘗試建立到綁定到addr指定地址的套接字的連接。一些協(xié)議套接字(例如UNIX域流套接字)可能只能成功地連接()一次。一些協(xié)議套接字(例如UNIX和Internet域中的數(shù)據(jù)報套接字)可能多次使用connect()來更改它們的關(guān)聯(lián)。一些協(xié)議套接字(例如,TCP套接字以及UNIX和Internet域中的數(shù)據(jù)報套接字)可以通過連接到帶有的地址來解除關(guān)聯(lián)sockaddr的sa_family成員設(shè)置為AF_UNSPEC;此后,套接字可以連接到另一個地址。(AF_UNSPEC自內(nèi)核2.2起在Linux上得到支持。)



int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

sockfd:產(chǎn)生的套接字參數(shù)

*addr:傳入?yún)?shù),指定服務(wù)器端地址信息,含IP地址和端口號

addrlen:第二個參數(shù)的長度

到這里,基本的通信所用到的函數(shù)就介紹完畢了,這兩天也找了很多資料,但是始終很難有一個茅塞頓開的醒悟,所以就先暫時到這吧,后面繼續(xù)學習,有了感悟,我會再后面重新再寫一遍函數(shù)的介紹,總的來說,對于accept、socket等函數(shù)印象很深刻,但是對于connect以及bind還是有點模糊的概念,因為我確實也沒搞定,某些參數(shù)的由來,雖然linux系統(tǒng)下面提供了源碼,我也看了一些,但是確實還是很難理解,但是我記得這里是一個疑點,往后面學習,我還會回來的!


上次少更新的兩個函數(shù),在后面學習的過程中我才發(fā)現(xiàn),現(xiàn)在先來簡單說一下啦
inet_pton();

說到最后這兩個函數(shù),就要提到一些概念性的定義,例如我們常見的IP:192.168.8.88,這是一個十進制的網(wǎng)絡(luò)字節(jié)序,但是在我們計算機中的網(wǎng)絡(luò)字節(jié)序,可不是這種,而是一種二進制的網(wǎng)絡(luò)字節(jié)序。

網(wǎng)絡(luò)字節(jié)序:

類型:大端字節(jié)序、小端字節(jié)序

大端:最高有效位存于最低內(nèi)存地址處,最低有效位存于最高內(nèi)存處;(低到高)

小端:最高有效位存于最高內(nèi)存地址,最低有效位存于最低內(nèi)存處。(高到低)

? ??

這里由于一些原因,導致我們電腦本機使用的是小端字節(jié)序,而在網(wǎng)絡(luò)中的數(shù)據(jù)傳輸使用的是大端字節(jié)序,因此在對數(shù)據(jù)進行傳世時,需要進行轉(zhuǎn)化。而現(xiàn)在也有著一些很合適的轉(zhuǎn)化函數(shù)

1.htons、htonl,解釋為Host to Network,從主機轉(zhuǎn)換到網(wǎng)路,也就是表明,講字節(jié)序由小端轉(zhuǎn)化為大端,兩個函數(shù)的區(qū)別主要是返回值的長短不同,s表示返回unsigned short int,l表示返回unsigned int


2、ntohs、ntohl,聽懂了上面的解釋,這兩個函數(shù)的意思就顯而易見了。Netword to Host,網(wǎng)絡(luò)中的大端字節(jié)序轉(zhuǎn)化為Host中的小端字節(jié)序。

后面的s、l是同一個意思,只是返回的值部同


明白了網(wǎng)絡(luò)字節(jié)序,就明白了數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸基本都是二進制形式的,但是我們還是會經(jīng)??吹絠p 192.128.66.255 193.253.255.21等等這些ip,但是這些ip有一個共同的特點,就是這些ip都使用了十進制來表示,但是在機器語言中,傳遞的數(shù)據(jù)可能是這樣0000. 0125.2352.1563

所以這里牽扯到如何講ip轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序的,這個地方就是我們今天要說的函數(shù),inet_pton,inet_ntop,

兩個函數(shù)就是將網(wǎng)絡(luò)字節(jié)序和正常人類能看懂的進行一個轉(zhuǎn)換,

1100.1200.1300.1400

所以在某些函數(shù)里面是需要使用十進制二維碼,當然也可以手動轉(zhuǎn)換

為此,這兩個函數(shù)起到十進制和網(wǎng)絡(luò)字節(jié)序之間的轉(zhuǎn)換。

inet_ntop();

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • https://www.cnblogs.com/skynet/archive/2010/12/12/1903949...
    gykimo閱讀 659評論 0 0
  • 簡介 Socket理論 Socket工作流程 核心函數(shù)講解 服務(wù)的如何獲取客戶端的信息 字符串ip和網(wǎng)絡(luò)二進制的轉(zhuǎn)...
    第八區(qū)閱讀 4,051評論 0 4
  • Linux內(nèi)核net/socket.c定義了一套socket的操作api。圖1展示了socket層所處與TCP/I...
    VictorHong閱讀 2,856評論 1 2
  • 1.1 網(wǎng)絡(luò)常識 1)網(wǎng)絡(luò)的7層網(wǎng)絡(luò)協(xié)議 ISO按照邏輯劃分出來7層網(wǎng)絡(luò)協(xié)議 應(yīng)用層:和應(yīng)用程序打交道的,進行數(shù)據(jù)...
    vera姐姐閱讀 523評論 0 1
  • 什么是TCP/IP、UDP? TCP/IP(Transmission Control Protocol/Inter...
    liuboxx1閱讀 1,053評論 0 1

友情鏈接更多精彩內(nèi)容