日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字

發(fā)布時(shí)間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
這里的“通訊”加上了引號(hào),是因?yàn)閷?shí)際上所有的socket都有通訊的功能,只是在我們的例子中,之前那個(gè)socket只負(fù)責(zé)listen,而這個(gè)socket負(fù)責(zé)接受信息并echo回去。
?我們現(xiàn)看看這個(gè)函數(shù):
bool?TcpServer::isAccept()
{
????unsigned?
int?clntAddrLen?=?sizeof(clntAddr);

????
if?(?(communicationSock?=?accept(listenSock,?(sockaddr*)&clntAddr,?&clntAddrLen))?<?0?)?{
????????
return?false;
????}?
else?{
????????std::cout?
<<?"Client(IP:?"?<<?inet_ntoa(clntAddr.sin_addr)?<<?")?connected.\n";
????????
return?true;
????}
}

用accept()創(chuàng)建新的socket

??????? 在我們的例子中,communicationSock實(shí)際上是用函數(shù)accept()創(chuàng)建的。
int?accept(int?socket,?struct?sockaddr*?clientAddress,?unsigned?int*?addressLength); 在Linux中的實(shí)現(xiàn)為:
/*?Await?a?connection?on?socket?FD.
???When?a?connection?arrives,?open?a?new?socket?to?communicate?with?it,
???set?*ADDR?(which?is?*ADDR_LEN?bytes?long)?to?the?address?of?the?connecting
???peer?and?*ADDR_LEN?to?the?address's?actual?length,?and?return?the
???new?socket's?descriptor,?or?-1?for?errors.

???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??
*/
extern?int?accept?(int?__fd,?__SOCKADDR_ARG?__addr,
???????????socklen_t?
*__restrict?__addr_len); 這個(gè)函數(shù)實(shí)際上起著構(gòu)造socket作用的僅僅只有第一個(gè)參數(shù)(另外還有一個(gè)不在這個(gè)函數(shù)內(nèi)表現(xiàn)出來的因素,后面會(huì)討論到),后面兩個(gè)指針都有副作用,在socket創(chuàng)建后,會(huì)將客戶端sockaddr的數(shù)據(jù)以及結(jié)構(gòu)體的大小傳回。
??????? 當(dāng)程序調(diào)用accept()的時(shí)候,程序有可能就停下來等accept()的結(jié)果。這就是我們前一小節(jié)說到的block(阻塞)。這如同我們調(diào)用std::cin的時(shí)候系統(tǒng)會(huì)等待輸入直到回車一樣。accept()是一個(gè)有可能引起block的函數(shù)。請(qǐng)注意我說的是“有可能”,這是因?yàn)閍ccept()的block與否實(shí)際上決定與第一個(gè)參數(shù)socket的屬性。這個(gè)文件描述符如果是block的,accept()就block,否則就不block。默認(rèn)情況下,socket的屬性是“可讀可寫”,并且,是阻塞的。所以,我們不修改socket屬性的時(shí)候,accept()是阻塞的。

accept()的另一面connect()

??????? accept()只是在server端被動(dòng)的等待,它所響應(yīng)的,是client端connect()函數(shù):
int?connect(int?socket,?struct?sockaddr*?foreignAddress,?unsigned?int?addressLength); 雖然我們這里不打算詳細(xì)說明這個(gè)client端的函數(shù),但是我們可以看出來,這個(gè)函數(shù)與之前我們介紹的bind()有幾分相似,特別在Linux的實(shí)現(xiàn)中:
/*?Open?a?connection?on?socket?FD?to?peer?at?ADDR?(which?LEN?bytes?long).
???For?connectionless?socket?types,?just?set?the?default?address?to?send?to
???and?the?only?address?from?which?to?accept?transmissions.
???Return?0?on?success,?-1?for?errors.

???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??
*/
extern?int?connect?(int?__fd,?__CONST_SOCKADDR_ARG?__addr,?socklen_t?__len); connect() 也使用了const的sockaddr,只不過是遠(yuǎn)程電腦上的而非bind()的本機(jī)。
??????? accept()在server端表面上是通過listen socket創(chuàng)建了新的socket,實(shí)際上,這種行為是在接受對(duì)方客戶機(jī)程序中connect()函數(shù)的請(qǐng)求后發(fā)生的。綜合起看,被創(chuàng)建的新socket實(shí)際上包含了listen socket的信息以及客戶端connect()請(qǐng)求中所包含的信息——客戶端的sockaddr地址。

新socket與sockaddr的關(guān)系

??????? accept()創(chuàng)建的新socket(我們例子中的communicationSock,這里我們簡(jiǎn)單用newSock來帶指)首先包含了listen socket的信息,所以,newSock具有本機(jī)sockaddr的信息;其次,因?yàn)樗憫?yīng)于client端connect()函數(shù)的請(qǐng)求,所以,它還包含了clinet端sockaddr的信息。
??????? 我們說過,stream流形式的TCP協(xié)議實(shí)際上是建立起一個(gè)“可來可去”的通道。用于listen的通道,遠(yuǎn)程機(jī)的目標(biāo)地址是不確定的;但是newSock卻是有指定的本機(jī)地址和遠(yuǎn)程機(jī)地址,所以,這個(gè)socket,才是我們真正用于TCP“通訊”的socket。

inet_ntoa()
#include?<arpa/inet.h>

/*?Convert?Internet?number?in?IN?to?ASCII?representation.??The?return?value
???is?a?pointer?to?an?internal?array?containing?the?string.??
*/
extern?char?*inet_ntoa?(struct?in_addr?__in)?__THROW; ??????? 對(duì)于這個(gè)函數(shù),我們可以作為一種,將IP地址,由in_addr結(jié)構(gòu)轉(zhuǎn)換為可讀的ASCII形式的固定用法。

總結(jié)

以上是生活随笔為你收集整理的socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。