對於sockte簡單的理解與整理

2021-07-11 09:54:24 字數 3501 閱讀 9429

建立套接字

intserv_sock

=socket

(af_inet

,sock_stream

,ipproto_tcp

);第乙個引數指定應用程式使用的通訊協議的協議族,對於tcp/ip協議族,該引數置

af_inet

;第二個引數指定要建立的套接字型別,流套接字型別為

sock_stream

、資料報套接字型別為

sock_dgram

、原始套接字

sock_raw

(winsock介面並不適用某種特定的協議去封裝它,而是由程式自行處理資料報以及協議首部);

第三個引數指定應用程式所使用的通訊協議。此引數可以指定單個協議系列中的不同傳輸協議。在internet通訊域中,此引數一般取值為0,系統會根據套接字的型別決定應使用的傳輸層協議。

socket返回值是乙個識別符號,後面的所有函式呼叫都使用這個識別符號來描述套接字。

struct

sockaddr_in serv_addr

;//就假設這個結構是套接字上面的目的位址,具體的我也不清楚啊

memset

(&serv_addr,0

,sizeof

(serv_addr

));//每個位元組都用0填充

serv_addr

.sin_family

=af_inet

;//使用ipv4位址,指定協議族

serv_addr

.sin_addr

.s_addr

=inet_addr

("127.0.0.1"

);serv_addr

.sin_port

=htons

(1234

);//埠:htons

是將整型變數從主機位元組順序轉變成網路位元組順序, 就是整數在位址空間儲存方式變為:高位位元組存放在記憶體的低位址處。

服務端服務端首先需要建立監聽套接字

bind

(serv_sock,(

struct

sockaddr

*)&serv_addr

,sizeof

(serv_addr

));//將套接字與目的位址繫結起來

listen

(serv_sock,20

);//

監聽套接字

客戶端注意客戶端並不會建立監聽套接字

connect

(sock,(

struct

sockaddr

*)&serv_addr

,sizeof

(serv_addr

));

然後服務端開啟,等待客戶端連線,然後建立乙個連線套接字

這兒可以用while(true)或者for(;;)來持續監聽來自客戶端的連線。

struct

sockaddr_in clnt_addr

;//客戶端傳過來的目的位址

socklen_t clnt_addr_size

=sizeof

(clnt_addr

);int

clnt_sock

=accept

(serv_sock,(

struct

sockaddr

*)&clnt_addr,&

clnt_addr_size);

如果客戶端有連線請求,必須使用下述函式來接受客戶端的請求。

socket accept(

socket               s,

struct sockaddr far  *addr,

int far          *addrlen

);

addr用於存放客戶端的位址,addrlen在呼叫函式時被設定為addr指向區域的長度,在函式呼叫結束後被設定為實際位址資訊的長度。本函式會阻塞等待直到有客戶端請求到達。

返回值是乙個新的套接字描述符,它代表的是和客戶端的新的連線,這個套接字就是連線套接字,包含的是客戶端的ip和port資訊 ,而引數中的socket   s包含的是伺服器的ip和port資訊 。(當然這個new_socket會從serv_sock中繼承 伺服器的ip和port資訊,兩種都有了,就組成了乙個套接字對,注意服務端與客戶端是通過套接字對聯絡的,tcp必須檢視套接字對的所有4個元素(客戶端/服務端的ip/port)才能確定由哪個端點接收某個達到的分組)。

系統呼叫   accept()   會有點古怪的地方的!你可以想象發生   這樣的事情:有人從很遠的地方通過乙個你在偵聽   (listen())   的埠連線   (connect())   到你的機器。它的連線將加入到等待接受   (accept())   的佇列   中。你呼叫   accept()   告訴它你有空閒的連線。它將返回乙個新的套接字文   件描述符!這樣你就有兩個套接字了,原來的乙個還在偵聽你的那個埠,   新的在準備傳送   (send())   和接收   (   recv())   資料。這就是這個過程! 

也就是說,在連線建立後,客戶端用發出連線的那個socket向伺服器發資料,是發給伺服器新建立的socket,而不是伺服器的監聽socket。伺服器的監聽socket永遠只是用來接受連線請求。

這就好比你去吃飯,飯館門口有迎賓小姐(監聽socket)看到你來後和你打招呼,然後(accept)找來乙個新的服務員(new socket)來接待你,然後守在門口繼續監聽下乙個。監聽的小姐走了,接待你的服務員當然不受影響。

建立連線套接字後就可以開始客戶端與服務端的聯絡

注意send/recv 及write/read的區別,這裡稍後再整理吧。

聯絡的話就可以幹很多事情了,balabala......

服務端

charstr

="hello world!"

;write

(clnt_sock

,str

,sizeof

(str

));//通過連線套接字對傳送訊息

客戶端char

buffer[40

];read

(sock

,buffer

,sizeof

(buffer)-1

);//通過連線套接字對接受訊息

printf

("message form server: %s\n"

,buffer

);//在客戶端顯示來自主機的訊息

最後通訊結束,關閉套接字對

close

(clnt_sock

);close

(serv_sock

);//注意服務端還需要關閉監聽套接字。

對於Stack的簡單理解

stack其實很簡單,感覺陌生的主要的原因是新手沒怎麼接觸過或者不常用,以及對stack本質上到底是什麼東西不清楚,如果知道了stack本質上到底是個什麼東西,stack就再簡單不過了。stack 本質上就是乙個 集合 跟 arraylist 集合一樣,都是儲存資料的乙個集合。因此,stack也就很...

對於ajax的簡單理解

jquery 中load 方法是簡單強大的ajax方法,這個方法是在從伺服器載入資料,並且返回資料放入選擇器選擇的元素中。它的語法結構是這樣的 selector load url,data,callback url是乙個必須引數,就是需要載入的url,date和callback是都是可選引數,dat...

對於epollout的簡單理解

今天聽大神說到了epoll 中的epollout 事件,我基本沒有用過這種東西,我並不知道這個有什麼用?epollout 主要是用來傳輸大量資料的時候,沒有辦法一次將資料全部傳送出去就需要將剩下的資料快取起來,等核心通知緩衝區可寫的時候再繼續傳送 epollout 在傳送大型檔案的時候需要進行處理,...