主頁(yè) > 知識(shí)庫(kù) > 詳解PHP Swoole與TCP三次握手

詳解PHP Swoole與TCP三次握手

熱門標(biāo)簽:地圖標(biāo)注平臺(tái)怎么給錢注冊(cè) 常州地圖標(biāo)注服務(wù)商 百度商鋪地圖標(biāo)注 衡水外呼系統(tǒng)平臺(tái) 注冊(cè)400電話申請(qǐng) 新河科技智能外呼系統(tǒng)怎么樣 安裝電銷外呼系統(tǒng) 釘釘打卡地圖標(biāo)注 福州人工外呼系統(tǒng)哪家強(qiáng)

握手常見問(wèn)題

1、連接拒絕

2、Operation now in progress 多是因?yàn)閬G包、錯(cuò)誤ip、backlog滿了阻塞tcp_abort_on_overflow=0

3、min(maxconn, backlog) ss -lt

連接拒絕

在TCP三次握手的時(shí)候,客戶端發(fā)送SYN這個(gè)包給服務(wù)端,服務(wù)端不接受這個(gè)請(qǐng)求,操作系統(tǒng)直接返回了一個(gè)RST的包,來(lái)拒絕連接的請(qǐng)求。

最常見的情況就是客戶端去請(qǐng)求某個(gè)服務(wù)器,服務(wù)端沒(méi)有綁定對(duì)應(yīng)的端口。

測(cè)試代碼如下,服務(wù)端代碼:

?php
​
$server = new \Swoole\Server('127.0.0.1', 9501);
​
$server->set([
    'work_num' => 2,
    'backlog' => 128,
]);
​
$server->on('connect', function ($server, $fd)
{
    echo "Client: Connect.\n";
});
​
$server->on('receive', function ($server, $fd, $reactor_id, $data)
{
    var_dump($data);
});
​
$server->on('close', function ()
{
    var_dump('close');
});
​
$server->start();

這里,服務(wù)端綁定的端口是9501。

啟動(dòng)服務(wù)器:

1 ~/codeDir/phpCode/hyperf-skeleton # php server.php 

客戶端代碼:

?php
​
$client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
var_dump($client->connect('127.0.0.1', 9500));

這里,客戶端請(qǐng)求的端口是9500。

啟動(dòng)客戶端:

~/codeDir/phpCode/hyperf-skeleton # php client.php 
​
Warning: Swoole\Client::connect(): connect to server[127.0.0.1:9500] failed, Error: Connection refused[111] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 4
bool(false)
~/codeDir/phpCode/hyperf-skeleton #

報(bào)錯(cuò):

Error: Connection refused[111]

Operation now in progress

這個(gè)錯(cuò)誤的絕大部分原因是因?yàn)檫B接超時(shí)了。

丟包

例如路由器、網(wǎng)關(guān)出現(xiàn)了故障,包被丟了。

錯(cuò)誤ip

例如客戶端請(qǐng)求了一個(gè)錯(cuò)誤的ip,那么路由器自然也就路由不到。

測(cè)試代碼如下,客戶端代碼:

?php
​
$client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
var_dump($client->connect('8.8.8.8', 9501));

這里,我訪問(wèn)的是谷歌的DNS服務(wù)器。因?yàn)槲覜](méi)有FQ,所以是訪問(wèn)不了這個(gè)IP的。因此,我們發(fā)送的包是到達(dá)不了8.8.8.8服務(wù)器的。

啟動(dòng)客戶端:

~/codeDir/phpCode/hyperf-skeleton # php client.php 
​
Warning: Swoole\Client::connect(): connect to server[8.8.8.8:9501] failed, Error: Operation in progress[115] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 4
bool(false)
~/codeDir/phpCode/hyperf-skeleton #

報(bào)錯(cuò):

Error: Operation in progress[115]

backlog

服務(wù)器在三次握手的最后一次,即收到客戶端發(fā)來(lái)的ACK包的時(shí)候,會(huì)把建立好的連接放到backlog隊(duì)列里面。如果Swoole一直不accept連接,那么這個(gè)backlog隊(duì)列很快就會(huì)滿。backlog隊(duì)列滿了之后,服務(wù)端就會(huì)丟棄三次握手的SYN包,讓客戶端重新去連接服務(wù)端。

測(cè)試代碼如下,服務(wù)端代碼:

?php
​
$server = new \Swoole\Server('127.0.0.1', 9501, SWOOLE_BASE);
​
$server->set([
    'work_num' => 2,
    'backlog' => 128,
]);
​
$server->on('connect', function ($server, $fd)
{
    echo "Client: Connect.\n";
    sleep(1000);
});
​
$server->on('receive', function ($server, $fd, $reactor_id, $data)
{
    var_dump($data);
});
​
$server->on('close', function ()
{
    var_dump('close');
});
​
$server->start();

要想測(cè)試backlog問(wèn)題必須在Swoole的SWOOLE_BASE模式下,默認(rèn)的SWOOLE_PROCESS模式是沒(méi)有這個(gè)問(wèn)題的。

這里,我們的backlog大小是128。

然后,我們通過(guò)sleep(1000);來(lái)阻塞住進(jìn)程,使得Swoole不會(huì)繼續(xù)accept連接,從而導(dǎo)致backlog隊(duì)列在某個(gè)時(shí)刻變滿。

客戶端代碼:

?php
​
$i = 0;
while (true)
{
    $client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
    if ($client->connect('127.0.0.1', 9501) == false)
    {
        break;
    }
}

我們啟動(dòng)服務(wù)器:

~/codeDir/phpCode/hyperf-skeleton # php server.php 

然后啟動(dòng)客戶端:

~/codeDir/phpCode/hyperf-skeleton # php client.php 
省略了其他的輸出
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
​
Warning: Swoole\Client::connect(): connect to server[127.0.0.1:9501] failed, Error: Operation in progress[115] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 7
bool(false)
​
Warning: Swoole\Client::connect(): connect to server[127.0.0.1:9501] failed, Error: Operation in progress[115] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 7
bool(false)
^C
~/codeDir/phpCode/hyperf-skeleton #

我們會(huì)發(fā)現(xiàn),過(guò)一段時(shí)間,客戶端這邊會(huì)報(bào)錯(cuò):

Error: Operation in progress[115]

服務(wù)端這邊輸出:

~/codeDir/phpCode/hyperf-skeleton # php server.php 

Client: Connect.

因?yàn)楫?dāng)Swoole服務(wù)器從backlog隊(duì)列里面accept一個(gè)連接的時(shí)候,才會(huì)觸發(fā)onReceive回調(diào)函數(shù)。所以,當(dāng)服務(wù)端accept一個(gè)連接之后,Swoole自己就會(huì)陷入阻塞,不會(huì)再accept了。但是需要注意的是,盡管Swoole服務(wù)器自身是阻塞的,操作系統(tǒng)還會(huì)繼續(xù)去把建立好的連接放入backlog隊(duì)列里面。所以,backlog隊(duì)列會(huì)滿。

SYN Flood

除了三次握手成功之后會(huì)使用到的backlog隊(duì)列,還有一個(gè)SYN隊(duì)列。也就是在三次握手時(shí)候,客戶端給服務(wù)端發(fā)送了SYN包,服務(wù)端會(huì)有一個(gè)SYN隊(duì)列來(lái)維護(hù)。

與其有關(guān)的內(nèi)核配置:

tcp_max_syn_backlog
tcp_synack_retries
tcp_syncookies

其中,tcp_max_syn_backlog就是這個(gè)SYN隊(duì)列的長(zhǎng)度。如果大量的SYN包把SYN隊(duì)列塞滿了,那么其他正常的連接過(guò)來(lái),服務(wù)端就無(wú)法處理。

SYN Flood攻擊就是客戶端瘋狂的給服務(wù)端發(fā)送SYN包,然后服務(wù)端每次都會(huì)把請(qǐng)求放到SYN隊(duì)列里面。但是,客戶端不給服務(wù)端回ACK包。如果客戶端不回ACK包,那么服務(wù)端就會(huì)給客戶端回SYN + ACK包,即第二次握手發(fā)送的包。而回復(fù)SYN + ACK包的次數(shù)就是由tcp_synack_retries參數(shù)決定的。如果把tcp_synack_retries設(shè)置為0,那么如果服務(wù)端沒(méi)有收到ACK包,那么服務(wù)端就不會(huì)重試發(fā)送SYN + ACK包了,這樣就減少了SYN隊(duì)列里面那個(gè)請(qǐng)求的存活時(shí)間。

tcp_syncookies的原理就是,客戶端發(fā)送SYN包的時(shí)候,不會(huì)維護(hù)SYN隊(duì)列,而是返回一個(gè)cookie給客戶端。然后客戶端發(fā)送第三次握手的時(shí)候,攜帶這個(gè)cookie值,只有這個(gè)cookie驗(yàn)證通過(guò),服務(wù)端才會(huì)給連接分配資源。

以上就是詳解PHP Swoole與TCP三次握手的詳細(xì)內(nèi)容,更多關(guān)于PHP Swoole與TCP三次握手的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • Swoole擴(kuò)展的6種模式深入詳解
  • php中Swoole的熱更新實(shí)現(xiàn)代碼實(shí)例
  • swoole鎖的機(jī)制代碼實(shí)例講解
  • windows系統(tǒng)php環(huán)境安裝swoole具體步驟
  • linux系統(tǒng)虛擬主機(jī)開啟支持Swoole Loader擴(kuò)展的方法
  • Swoole源碼中如何查詢Websocket的連接問(wèn)題詳解
  • 在Windows系統(tǒng)上安裝Cygwin搭建Swoole測(cè)試環(huán)境的圖文教程
  • php使用goto實(shí)現(xiàn)自動(dòng)重啟swoole、reactphp、workerman服務(wù)的代碼
  • Centos7安裝swoole擴(kuò)展操作示例
  • 詳解Swoole TCP流數(shù)據(jù)邊界問(wèn)題解決方案

標(biāo)簽:六安 唐山 遼陽(yáng) 鷹潭 白城 克拉瑪依 鶴崗 柳州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解PHP Swoole與TCP三次握手》,本文關(guān)鍵詞  詳解,PHP,Swoole,與,TCP,三次,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解PHP Swoole與TCP三次握手》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于詳解PHP Swoole與TCP三次握手的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章