⑴ 服務暫時不可用.請稍後再試.
可能是伺服器忙或者是連接超時,重新試一下
⑵ 請教一下 php 如何測試SMTP埠是否能正常連通
<?php
/**需要擴展模塊extension=php_sockets.dll
*Filenameserver.php
*伺服器端代碼
*
*@authorguisu.huang
*@since2012-04-11
*
*/
//確保在連接客戶端時不會超時
set_time_limit(0);
//設置IP和埠號
$address="127.0.0.1";
$port=2046;//調試的時候,可以多換埠來測試程序!
/**
*創建一個SOCKET
*AF_INET=是ipv4如果用ipv6,則參數為AF_INET6
*SOCK_STREAM為socket的tcp類型,如果是UDP則使用SOCK_DGRAM
*/
$sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)ordie("socket_create()失敗的原因是:".socket_strerror(socket_last_error())."/n");
//阻塞模式
socket_set_block($sock)ordie("socket_set_block()失敗的原因是:".socket_strerror(socket_last_error())."/n");
//綁定到socket埠
$result=socket_bind($sock,$address,$port)ordie("socket_bind()失敗的原因是:".socket_strerror(socket_last_error())."/n");
//開始監聽
$result=socket_listen($sock,4)ordie("socket_listen()失敗的原因是:".socket_strerror(socket_last_error())."/n");
echo"OK Bindingthesocketon$address:$port...";
echo"OK Nowreadytoacceptconnections. Listeningonthesocket... ";
do{//neverstopthedaemon
//它接收連接請求並調用一個子連接Socket來處理客戶端和伺服器間的信息
$msgsock=socket_accept($sock)ordie("socket_accept()failed:reason:".socket_strerror(socket_last_error())."/n");
//讀取客戶端數據
echo"Readclientdata ";
//socket_read函數會一直讀取客戶端數據,直到遇見 , 或者 字元.PHP腳本把這寫字元看做是輸入的結束符.
$buf=socket_read($msgsock,8192);
echo"Receivedmsg:$buf ";
//數據傳送向客戶端寫入返回結果
$msg="welcome ";
socket_write($msgsock,$msg,strlen($msg))ordie("socket_write()failed:reason:".socket_strerror(socket_last_error())."/n");
//一旦輸出被返回到客戶端,父/子socket都應通過socket_close($msgsock)函數來終止
socket_close($msgsock);
}while(true);
socket_close($sock);
⑶ tcp的連接數量受synqueue限制嗎
tcp的連接數量受synqueue限制嗎:
在實際工作中經常碰到一種情況,流量上漲的時候,服務端會出現大量的超時。此時的處理辦法一般是擴容。
實際上就算沒有流量上漲,當某個介面速度變慢時,調用該介面的服務也會出現超時。
不管是流量上漲(qps增加)還是介面變慢,導致超時的直接原因都是系統吞吐量不足(系統吞吐量 = qps / 響應時間)。
當系統吞吐量不足時,大量請求就會在介面上堆積得不到及時的處理,表現出來就是連接超時或介面超時。
TCP半連接隊列和全連接隊列
創建tcp連接時需要三次握手。
首先客戶端向服務端發送一個連接請求,包含一個SYN包,客戶端進入SYN_SEND狀態。
服務端收到客戶端的請求後將返回一個SYN+ACK,此時服務端進入SYN_RECV狀態。服務端內核會將該連接存儲到半連接隊列(SYN隊列)。
客戶端收到服務端的確認後,發送一個ACK包,此時客戶端進入ESTABLISHED狀態。
服務端收到客戶端發來的ACK包之後,進入ESTABLISHED狀態,並將半連接隊列中的連接取出來放到全連接隊列里(ACCEPT隊列)。等待進程調用accept函數時將連接取出來。
整體流程如下圖所示:
不管是半連接隊列(syn queue)還是全連接隊列(accept queue),都是有長度限制的,超過長度限制時,內核會直接丟棄或者返回RST包。
查看全連接隊列
可以使用ss(比netstat更快)命令查看tcp全連接隊列的情況。
# -l 顯示處於listen狀態的socket
# -n 不解析服務名稱
# -t 只顯示tcp socket
ss -lnt
1
2
3
4
1
2
3
4
結果如下:
其中,Recv-Q表示全連接隊列的大小,也就是已完成三次握手並等待服務端accept()的tcp連接個數。Send-Q表示全連接最大隊列長度,默認是128。
注意在非Listen狀態下(不使用-l參數),Recv-Q/Send-Q表示的含義是不同的。
其中Recv-Q表示已收到但未被應用進程讀取的位元組數。Send-Q表示已發送到未收到確認的位元組數。
打開CSDN APP,看更多技術內容
TCP 全連接隊列滿了會發生什麼?又該如何應對?_YY小記的博客_t...
如果伺服器上的進程只是短暫的繁忙造成 accept 隊列滿,那麼當 TCP 全連接隊列有空位時,再次接收到的請求報文由於含有 ACK,仍然會觸發伺服器端成功建立連接。 所以,tcp_abort_on_overflow 設為 0 可以提高連接建立的成功率,只有你非常肯...
繼續訪問
最大TCP連接數量問題總結_星期二的風的博客_tcp連接數
TCP連接數過大可能會出現: ERROR: out of memory ,即內存溢出。 原因:每個TCP連接本身,以及這個連接所用到的緩沖區,都是需要佔用一定內存的,現在內存已經被占滿了,不夠用了就會報這個錯。 5、CPU的限制 每個TCP連接都是需要佔用CPU...
繼續訪問
伺服器遠程超出最大連接數的原因及解決
伺服器遠程超出最大連接數的原因是沒有注銷退出有可能導致遠程連接的進程死掉,重啟伺服器即可
熱門推薦 解決TCP連接數過多的問題
1、建立連接協議(三次握手) (1)客戶 端發送一個帶SYN標志的TCP報文到伺服器。這是三次握手過程中的報文1。 (2) 伺服器端回應客戶端的,這是三次握手中的第2個報文,這個報文同時帶ACK標志和SYN標 志。因此它表示對剛才客戶端SYN報文的回應;同時又標志SYN給客戶端,詢問客戶端是否准備好進行數據通 訊。 (3) 客戶必須再次回應服務段一個ACK報文,這是報文段3。 2、連接終止
繼續訪問
記一次線上環境tcp鏈接爆滿導致服務響應慢的問題_徐波_bobch的博客...
記一次線上環境tcp鏈接爆滿導致服務響應慢的問題 事件還原: 20200407凌晨接到運維人員電話,說app啟動充電響應很慢,無法正常的開啟充電; 20200407凌晨,跟蹤日誌排查服務負載情況,但是過了一段時間自動恢復; ...
繼續訪問
伺服器tcp連接占滿_伺服器出現大量TIME_WAIT解決方案
一 、故障原因: 伺服器突然出現大量time_wait(因為大量連接資源被佔用後不釋放的話,會導致網站正常訪問不能響應)。如何應對?我這邊先檢查了監控和伺服器當前的狀態(time_wait連接確實異常):1、監控2、登錄伺服器檢查二、排查思路:1、猜測是否因為程序打開大量文件句柄,沒有關閉導致。(問了研發同事,排查過後沒有這種情況)2、調大當前文件句柄 3、調優sysctl.conf文件4、檢查n...
繼續訪問
性能分析之壓測中 TCP 全連接隊列占滿問題分析及優化案例
文章目錄一、前言二、知識預備三、壓測及分析過程1、第一次壓測2、調大 backlog 值為 5000 後,再次壓測3、調整日誌級別為 ERROR,再次壓測四、小結 一、前言 在對一個擋板系統進行測試時,遇到一個由於 TCP 全連接隊列被占滿而影響系統性能的問題,這里記錄下如何進行分析及解決的。 二、知識預備 理解下 TCP 建立連接過程與隊列: 從圖中明顯可以看出建立 TCP 連接的時候,有兩個隊列:syns queue(半連接隊列)和accept queue(全連接隊列),分別在第一次握手和第三次握手。
繼續訪問
TCP全連接隊列和半連接隊列已滿之後的連接建立過程抓包分析
在進行client不斷的對server端進行connect的過程中發現下面這個狀態,而且循環6w次的鏈接只進行了2W多次就出錯了。 於是去查找了下原因: linux內核協議棧為一個tcp連接管理使用兩個隊列,一個是半鏈接隊列(用來保存處於SYN_SENT和SYN_RECV狀態的請求),一個是全連接隊列(accpetd隊列)(用來保存處
繼續訪問
最大TCP連接數量問題總結
TCP連接限制問題總結最大TCP連接數量問題總結1、可用埠號限制2、文件描述符限制3、線程的限制4、內存的限制5、CPU的限制總結參考文獻: 最大TCP連接數量問題總結 直接上答案 最大TCP連接數量限制有:可用埠號數量、文件描述符數量、線程、內存、CPU 1、可用埠號限制 Q:一台主機可以有多少埠號?埠號與TCP連接?是否能修改?埠號限制因素? 第一:埠號是16位的,所以總共有65535個,即可創建65535個TCP連接 第二:埠分為知名埠(0~1023)、注冊埠(1024~4951
繼續訪問
關於TCP連接的一些細節問題
Q: 半連接隊列與全連接隊列 A: 半連接隊列:由tcp_max_syn_backlog決定,開戶syncookies時,沒有上限 全連接隊列:由somaxconn(系統級)與backlog(listen函數參數)共同決定,取兩者中的較小值 Q: 半連接隊列滿了如何處理? A: 丟棄請求 Q: 全連接隊列滿了如何處理? tcp_abort_on_overflow==1 發送reset包 tcp_abort_on_overflow==0 過一段時間重發syn ack包(次數由tcp_synack_ret
繼續訪問
linux下tcp伺服器並發連接數限制
1、修改用戶進程可打開文件數限制 在Linux平台上,無論編寫客戶端程序還是服務端程序,在進行高並發TCP連接處理時,最高的並發數量都要受到系統對用戶單一進程同時可打開文件數量的限制(這是因為系統為每個TCP連接都要創建一個socket句柄,每個socket句柄同時也是一個文件句柄)。可使用ulimit命令查看系統允許當前用戶進程打開的文件數限制: [speng@as4 ~]$ ulimit -n 1024 這表示當前用戶的每個進程最多允許同時打開1024個文件,這1024個文件中還得除去每個進程必然打開的
繼續訪問
linux syn 隊列,TCP SYN隊列與Accept隊列詳解
李樂盡信書,不如無書。紙上得來終覺淺,絕知此事要躬行。實驗現象依賴於系統(如下)以及內核參數(附錄);一切以實驗結果為准。cat /proc/versionLinux version 3.10.0-693.el7.x86_64引子線上服務(Golang)調用內網API服務(經由內網網關/Nginx轉發)時,偶爾會出現"connection reset by peer"報警;為此梳理TCP RST包...
繼續訪問
最新發布 計算機網路之TCP最大連接限制
計算機網路之TCP最大連接限制
繼續訪問
TCP半連接隊列要是滿了會怎麼樣?
一般是丟棄,但這個行為可以通過tcp_syncookies參數去控制。但比起這個,更重要的是先了解下半連接隊列為什麼會被打滿。 首先我們需要明白,一般情況下,半連接的"生存"時間其實很短,只有在第一次和第三次握手間,如果半連接都滿了,說明服務端瘋狂收到第一次握手請求,如果是線上游戲應用,能有這么多請求進來,那說明你可能要富了。但現實往往比較骨感,你可能遇到了SYN Flood攻擊。 所謂SYN Flood攻擊,可以簡單理解為,攻擊方模擬客戶端瘋狂發第一次握手請求過來,在服務端憨憨地回復第二次握手過去..
繼續訪問
TCP 全連接隊列滿了會發生什麼?又該如何應對?
什麼是 TCP 半連接隊列和全連接隊列? .半連接隊列,也稱 SYN 隊列; .全連接隊列,也稱 accepet 隊列; 服務端收到客戶端發起的 SYN 請求後,內核會把該連接存儲到半連接隊列,並向客戶端響應 SYN+ACK,接著客戶端會返回 ACK,服務端收到第三次握手的 ACK 後,內核會把連接從半連接隊列移除,然後創建新的完全的連接,並將其添加到 accept 隊列,等待進程調用 accept 函數時把連接取出來。 不管是半連接隊列還是全連接隊列,都有最大長度限制,超過限制時,內核會直接丟棄,或返回
繼續訪問
tcp連接大量time_wait
time_wait過多的後果 http://blog.51cto.com/benpaozhe/1767612 tcp基礎:http://blog.sciencenet.cn/blog-1225851-830338.html 連接不上的問題:http://www.cnxct.com/something-about-phpfpm-s-backlog/ http://maoyi.iteye.
繼續訪問
TCP accept返回的socket,服務端TCP連接數限制
http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html socket accept()返回的socket描述符的埠和listen描述符埠是一樣的嗎? as you know,一個socket是由一個五元組來唯一標示的,即(協議,server_ip, server_port, client_ip, client
繼續訪問
syn重發_TCP 網路傳輸協議中的全隊列和半隊列說明和半連接隊列的SYN洪水攻擊 | IT工程師的生活足跡...
一、TCP 維護隊列TCP協議在數據傳輸過程中會維護兩個隊列:半連接隊列(SYN queue)和全連接隊列(accept queue)。1.1、半連接隊列(SYN Queue)伺服器端監聽TCP埠後,會創建一個request_sock結構,用於存儲半連接隊列。在TCP三次握手中,當伺服器接受到客戶端的SYN包後,就將此連接保存到SYN Queue中,並向客戶端發送SYN-ACK包;等待客戶端發送...
繼續訪問
linux tcp連接滿了,[TimLinux] TCP全連接隊列滿
0. TCP三次握手syns queue: 半連接隊列accept queue: 全連接隊列控制參數存放在文件:/proc/sys/net/ipv4/tcp_abort_on_overflow中,0:表示如果三次握手第三步的時候全連接隊列滿了,那麼server扔掉client發過來的ack(在server端因為全連接隊列滿了,認為連接還沒有建立起來),1:表示第三步的時候如果全連接隊列滿了,ser...
繼續訪問
TCP全鏈接隊列滿的問題分析之net.core.somaxconn詳解
背景參考:TCP全鏈接隊列滿的問題分析之net.core.somaxconn詳解_運維_PHP面試網 最近控制台查看騰訊雲伺服器狀態時,發現一個異常情況提示如下: 該實例最近12小時內在2022-01-18 14:48出現過TCP全鏈接隊列滿的情況,為避免成為業務瓶頸,建議您檢查業務健康情況。可參考文檔:點擊查看 TCP 全連接隊列滿 TCP 全連接隊列的長度取net.core.somaxconn及業務進程調用 listen 時傳入的 backlog 參數,兩者中的較小值。若您的實..
繼續訪
⑷ 幾種常見的PHP超時處理方法
【Web伺服器超時處理】
[ Apache ]
一般在性能很高的情況下,預設所有超時配置都是30秒,但是在上傳文件,或者網路速度很慢的情況下,那麼可能觸發超時操作。
目前apachefastcgiphp-fpm模式下有三個超時設置:
fastcgi超時設置:
修改的fastcgi連接配置,類似如下:
復制代碼 代碼如下:
<IfMolemod_fastcgi.c>
FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock
ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"
AddHandlerphp-fastcgi.php
Actionphp-fastcgi/fcgi-bin/php-cgi
AddTypeapplication/x-
</IfMole>
預設配置是30s,如果需要定製自己的配置,需要修改配置,比如修改為100秒:(修改後重啟apache):
復制代碼 代碼如下:
<IfMolemod_fastcgi.c>
FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock-idle-timeout100
ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"
AddHandlerphp-fastcgi.php
Actionphp-fastcgi/fcgi-bin/php-cgi
AddTypeapplication/x-
</IfMole>
如果超時會返回500錯誤,斷開跟後端php服務的連接,同時記錄一條apache錯誤日誌:
[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI:commwithserver"/home/forum/apache/apache_php/cgi-bin/php-cgi"aborted:idletimeout(30sec)
[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI:incompleteheaders(0bytes)receivedfromserver"/home/forum/apache/apache_php/cgi-bin/php-cgi"
其他fastcgi配置參數說明:
復制代碼 代碼如下:
IdleTimeout發呆時限
ProcessLifeTime一個進程的最長生命周期,過期之後無條件kill
MaxProcessCount最大進程個數
DefaultMinClassProcessCount每個程序啟動的最小進程個數
DefaultMaxClassProcessCount每個程序啟動的最大進程個數
IPCConnectTimeout程序響應超時時間
IPCCommTimeout與程序通訊的最長時間,上面的錯誤有可能就是這個值設置過小造成的
MaxRequestsPerProcess每個進程最多完成處理個數,達成後自殺
[ Lighttpd ]
配置:lig
Lighttpd配置中,關於超時的參數有如下幾個(篇幅考慮,只寫讀超時,寫超時參數同理):
主要涉及選項:
server.max-keep-alive-idle=5
server.max-read-idle=60
server.read-timeout=0
server.max-connection-idle=360
復制代碼 代碼如下:
#每次keep-alive的最大請求數,默認值是16
server.max-keep-alive-requests=100
#keep-alive的最長等待時間,單位是秒,默認值是5
server.max-keep-alive-idle=1200
#lighttpd的work子進程數,默認值是0,單進程運行
server.max-worker=2
#限制用戶在發送請求的過程中,最大的中間停頓時間(單位是秒),
#如果用戶在發送請求的過程中(沒發完請求),中間停頓的時間太長,lighttpd會主動斷開連接
#默認值是60(秒)
server.max-read-idle=1200
#限制用戶在接收應答的過程中,最大的中間停頓時間(單位是秒),
#如果用戶在接收應答的過程中(沒接完),中間停頓的時間太長,lighttpd會主動斷開連接
#默認值是360(秒)
server.max-write-idle=12000
#讀客戶端請求的超時限制,單位是秒,配為0表示不作限制
#設置小於max-read-idle時,read-timeout生效
server.read-timeout=0
#寫應答頁面給客戶端的超時限制,單位是秒,配為0表示不作限制
#設置小於max-write-idle時,write-timeout生效
server.write-timeout=0
#請求的處理時間上限,如果用了mod_proxy_core,那就是和後端的交互時間限制,單位是秒
server.max-connection-idle=1200
說明:
對於一個keep-alive連接上的連續請求,發送第一個請求內容的最大間隔由參數max-read-idle決定,從第二個請求起,發送請求內容的最大間隔由參數max-keep-alive-idle決定。請求間的間隔超時也由max-keep-alive-idle決定。發送請求內容的總時間超時由參數read-timeout決定。Lighttpd與後端交互數據的超時由max-connection-idle決定。
延伸閱讀:
[ Nginx ]
配置:nf
復制代碼 代碼如下:
http{
#Fastcgi:(針對後端的fastcgi生效,fastcgi不屬於proxy模式)
fastcgi_connect_timeout5;#連接超時
fastcgi_send_timeout10; #寫超時
fastcgi_read_timeout10;#讀取超時
#Proxy:(針對proxy/upstreams的生效)
proxy_connect_timeout15s;#連接超時
proxy_read_timeout24s;#讀超時
proxy_send_timeout10s; #寫超時
}
說明:
Nginx 的超時設置倒是非常清晰容易理解,上面超時針對不同工作模式,但是因為超時帶來的問題是非常多的。
延伸閱讀:
ml
ml
ml
【PHP本身超時處理】
[ PHP-fpm ]
配置:nf
復制代碼 代碼如下:
<?xmlversion="1.0"?>
<configuration>
//...
.
.
EquivalenttoPHP_FCGI_.fcgi
Usedwithanypm_style.
#php-cgi的進程數量
<valuename="max_children">128</value>
Thetimeout(inseconds)
Shouldbeusedwhen'max_execution_time'
'0s'means'off'
#php-fpm 請求執行超時時間,0s為永不超時,否則設置一個 Ns 為超時的秒數
<valuename="request_terminate_timeout">0s</value>
Thetimeout(inseconds).logfile
'0s'means'off'
<valuename="request_slowlog_timeout">0s</value>
</configuration>
說明:
在php.ini中,有一個參數max_execution_time可以設置PHP腳本的最大執行時間,但是,在php-cgi(php-fpm)中,該參數不會起效。真正能夠控制PHP腳本最大執行時:
<valuename="request_terminate_timeout">0s</value>
就是說如果是使用mod_php5.so的模式運行max_execution_time是會生效的,但是如果是php-fpm模式中運行時不生效的。
延伸閱讀:
[ PHP ]
配置:php.ini
選項:
max_execution_time=30
或者在代碼里設置:
ini_set("max_execution_time",30);
set_time_limit(30);
說明:
對當前會話生效,比如設置0一直不超時,但是如果php的safe_mode打開了,這些設置都會不生效。
效果一樣,但是具體內容需要參考php-fpm部分內容,如果php-fpm中設置了request_terminate_timeout的話,那麼max_execution_time就不生效。
【後端&介面訪問超時】
【HTTP訪問】
一般我們訪問HTTP方式很多,主要是:curl,socket,file_get_contents()等方法。
如果碰到對方伺服器一直沒有響應的時候,我們就悲劇了,很容易把整個伺服器搞死,所以在訪問http的時候也需要考慮超時的問題。
[ CURL 訪問HTTP]
CURL 是我們常用的一種比較靠譜的訪問HTTP協議介面的lib庫,性能高,還有一些並發支持的功能等。
CURL:
curl_setopt($ch,opt)可以設置一些超時的設置,主要包括:
*(重要)CURLOPT_TIMEOUT設置cURL允許執行的最長秒數。
*(重要)CURLOPT_TIMEOUT_MS設置cURL允許執行的最長毫秒數。(在cURL7.16.2中被加入。從PHP5.2.3起可使用。)
CURLOPT_CONNECTTIMEOUT在發起連接前等待的時間,如果設置為0,則無限等待。
CURLOPT_CONNECTTIMEOUT_MS嘗試連接等待的時間,以毫秒為單位。如果設置為0,則無限等待。在cURL7.16.2中被加入。從PHP5.2.3開始可用。
CURLOPT_DNS_CACHE_TIMEOUT設置在內存中保存DNS信息的時間,默認為120秒。
curl普通秒級超時:
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_TIMEOUT,60);//只需要設置一個秒的數量就可以
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_USERAGENT,$defined_vars['HTTP_USER_AGENT']);
curl普通秒級超時使用:
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl如果需要進行毫秒超時,需要增加:
curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1L);
或者是:
curl_setopt($ch,CURLOPT_NOSIGNAL,true);是可以支持毫秒級別超時設置的
curl一個毫秒級超時的例子:
復制代碼 代碼如下:
<?php
if(!isset($_GET['foo'])){
//Client
$ch=curl_init('');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_NOSIGNAL,1);//注意,毫秒超時一定要設置這個
curl_setopt($ch,CURLOPT_TIMEOUT_MS,200);//超時毫秒,cURL7.16.2中被加入。從PHP5.2.3起可使用
$data=curl_exec($ch);
$curl_errno=curl_errno($ch);
$curl_error=curl_error($ch);
curl_close($ch);
if($curl_errno>0){
echo"cURLError($curl_errno):$curl_errorn";
}else{
echo"Datareceived:$datan";
}
}else{
//Server
sleep(10);
echo"Done.";
}
?>
其他一些技巧:
1. 按照經驗總結是:cURL版本>=libcurl/7.21.0版本,毫秒級超時是一定生效的,切記。
2. curl_multi的毫秒級超時也有問題。。單次訪問是支持ms級超時的,curl_multi並行調多個會不準
[流處理方式訪問HTTP]
除了curl,我們還經常自己使用fsockopen、或者是file操作函數來進行HTTP協議的處理,所以,我們對這塊的超時處理也是必須的。
一般連接超時可以直接設置,但是流讀取超時需要單獨處理。
自己寫代碼處理:
復制代碼 代碼如下:
$tmCurrent=gettimeofday();
$intUSGone=($tmCurrent['sec']-$tmStart['sec'])*1000000
+($tmCurrent['usec']-$tmStart['usec']);
if($intUSGone>$this->_intReadTimeoutUS){
returnfalse;
}
或者使用內置流處理函數stream_set_timeout()和stream_get_meta_data()處理:
復制代碼 代碼如下:
<?php
//Timeoutinseconds
$timeout=5;
$fp=fsockopen("",80,$errno,$errstr,$timeout);
if($fp){
fwrite($fp,"GET/HTTP/1.0rn");
fwrite($fp,"Host:rn");
fwrite($fp,"Connection:Closernrn");
stream_set_blocking($fp,true);//重要,設置為非阻塞模式
stream_set_timeout($fp,$timeout);//設置超時
$info=stream_get_meta_data($fp);
while((!feof($fp))&&(!$info['timed_out'])){
$data.=fgets($fp,4096);
$info=stream_get_meta_data($fp);
ob_flush;
flush();
}
if($info['timed_out']){
echo"ConnectionTimedOut!";
}else{
echo$data;
}
}
file_get_contents超時:
復制代碼 代碼如下:
<?php
$timeout=array(
'http'=>array(
'timeout'=>5//設置一個超時時間,單位為秒
)
);
$ctx=stream_context_create($timeout);
$text=file_get_contents("",0,$ctx);
?>
fopen超時:
復制代碼 代碼如下:
<?php
$timeout=array(
'http'=>array(
'timeout'=>5//設置一個超時時間,單位為秒
)
);
$ctx=stream_context_create($timeout);
if($fp=fopen("","r",false,$ctx)){
while($c=fread($fp,8192)){
echo$c;
}
fclose($fp);
}
?>
【MySQL】
php中的mysql客戶端都沒有設置超時的選項,mysqli和mysql都沒有,但是libmysql是提供超時選項的,只是我們在php中隱藏了而已。
那麼如何在PHP中使用這個操作捏,就需要我們自己定義一些MySQL操作常量,主要涉及的常量有:
MYSQL_OPT_READ_TIMEOUT=11;
MYSQL_OPT_WRITE_TIMEOUT=12;
這兩個,定義以後,可以使用options設置相應的值。
不過有個注意點,mysql內部實現:
1.超時設置單位為秒,最少配置1秒
2.但mysql底層的read會重試兩次,所以實際會是3秒
重試兩次+自身一次=3倍超時時間,那麼就是說最少超時時間是3秒,不會低於這個值,對於大部分應用來說可以接受,但是對於小部分應用需要優化。
查看一個設置訪問mysql超時的php實例:
復制代碼 代碼如下:
<?php
//自己定義讀寫超時常量
if(!defined('MYSQL_OPT_READ_TIMEOUT')){
define('MYSQL_OPT_READ_TIMEOUT',11);
}
if(!defined('MYSQL_OPT_WRITE_TIMEOUT')){
define('MYSQL_OPT_WRITE_TIMEOUT',12);
}
//設置超時
$mysqli=mysqli_init();
$mysqli->options(MYSQL_OPT_READ_TIMEOUT,3);
$mysqli->options(MYSQL_OPT_WRITE_TIMEOUT,1);
//連接資料庫
$mysqli->real_connect("localhost","root","root","test");
if(mysqli_connect_errno()){
printf("Connectfailed:%s/n",mysqli_connect_error());
exit();
}
//執行查詢sleep1秒不超時
printf("Hostinformation:%s/n",$mysqli->host_info);
if(!($res=$mysqli->query('selectsleep(1)'))){
echo"query1error:".$mysqli->error."/n";
}else{
echo"Query1:querysuccess/n";
}
//執行查詢sleep9秒會超時
if(!($res=$mysqli->query('selectsleep(9)'))){
echo"query2error:".$mysqli->error."/n";
}else{
echo"Query2:querysuccess/n";
}
$mysqli->close();
echo"closemysqlconnection/n";
?>
延伸閱讀:
【Memcached】
[PHP擴展]
php_memcache客戶端:
連接超時:boolMemcache::connect(string$host[,int$port[,int$timeout]])
在get和set的時候,都沒有明確的超時設置參數。
libmemcached客戶端:在php介面沒有明顯的超時參數。
說明:所以說,在PHP中訪問Memcached是存在很多問題的,需要自己hack部分操作,或者是參考網上補丁。
[C&C++訪問Memcached]
客戶端:libmemcached客戶端
說明:memcache超時配置可以配置小點,比如5,10個毫秒已經夠用了,超過這個時間還不如從資料庫查詢。
下面是一個連接和讀取set數據的超時的C++示例:
復制代碼 代碼如下:
//創建連接超時(連接到Memcached)
memcached_st*MemCacheProxy::_create_handle()
{
memcached_st*mmc=NULL;
memcached_return_tprc;
if(_mpool!=NULL){//getfrompool
mmc=memcached_pool_pop(_mpool,false,&prc);
if(mmc==NULL){
__LOG_WARNING__("MemCacheProxy","gethandlefrompoolerror[%d]",(int)prc);
}
returnmmc;
}
memcached_st*handle=memcached_create(NULL);
if(handle==NULL){
__LOG_WARNING__("MemCacheProxy","create_handleerror");
returnNULL;
}
//設置連接/讀取超時
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_HASH,MEMCACHED_HASH_DEFAULT);
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_NO_BLOCK,_noblock);//參數MEMCACHED_BEHAVIOR_NO_BLOCK為1使超時配置生效,不設置超時會不生效,關鍵時候會悲劇的,容易引起雪崩
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,_connect_timeout);//連接超時
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_RCV_TIMEOUT,_read_timeout);//讀超時
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_SND_TIMEOUT,_send_timeout);//寫超時
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_POLL_TIMEOUT,_poll_timeout);
//設置一致hash
//memcached_behavior_set_distribution(handle,MEMCACHED_DISTRIBUTION_CONSISTENT);
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMCACHED_DISTRIBUTION_CONSISTENT);
memcached_returnrc;
for(uinti=0;i<_server_count;i++){
rc=memcached_server_add(handle,_ips[i],_ports[i]);
if(MEMCACHED_SUCCESS!=rc){
__LOG_WARNING__("MemCacheProxy","addserver[%s:%d]failed.",_ips[i],_ports[i]);
}
}
_mpool=memcached_pool_create(handle,_min_connect,_max_connect);
if(_mpool==NULL){
__LOG_WARNING__("MemCacheProxy","create_poolerror");
returnNULL;
}
mmc=memcached_pool_pop(_mpool,false,&prc);
if(mmc==NULL){
__LOG_WARNING__("MyMemCacheProxy","gethandlefrompoolerror[%d]",(int)prc);
}
//__LOG_DEBUG__("MemCacheProxy","gethandle[%p]",handle);
returnmmc;
}
//設置一個key超時(set一個數據到memcached)
boolMemCacheProxy::_add(memcached_st*handle,unsignedint*key,constchar*value,intlen,unsignedinttimeout)
{
memcached_returnrc;
chartmp[1024];
snprintf(tmp,sizeof(tmp),"%u#%u",key[0],key[1]);
//有個timeout值
rc=memcached_set(handle,tmp,strlen(tmp),(char*)value,len,timeout,0);
if(MEMCACHED_SUCCESS!=rc){
returnfalse;
}
returntrue;
}
//Memcache讀取數據超時(沒有設置)
libmemcahed源碼中介面定義:
LIBMEMCACHED_APIchar*memcached_get(memcached_st*ptr,constchar*key,size_tkey_length,size_t*value_length,uint32_t*flags,memcached_return_t*error);
LIBMEMCACHED_APImemcached_return_tmemcached_mget(memcached_st*ptr,constchar*const*keys,constsize_t*key_length,size_tnumber_of_keys);
從介面中可以看出在讀取數據的時候,是沒有超時設置的。
延伸閱讀:
【如何實現超時】
程序中需要有超時這種功能,比如你單獨訪問一個後端Socket模塊,Socket模塊不屬於我們上面描述的任何一種的時候,它的協議也是私有的,那麼這個時候可能需要自己去實現一些超時處理策略,這個時候就需要一些處理代碼了。
[PHP中超時實現]
一、初級:最簡單的超時實現 (秒級超時)
思路很簡單:鏈接一個後端,然後設置為非阻塞模式,如果沒有連接上就一直循環,判斷當前時間和超時時間之間的差異。
phpsocket中實現原始的超時:(每次循環都當前時間去減,性能會很差,cpu佔用會較高)
復制代碼 代碼如下:
<?
$host="127.0.0.1";
$port="80";
$timeout=15;//timeoutinseconds
$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)
ordie("Unabletocreatesocketn");
socket_set_nonblock($socket) //務必設置為阻塞模式
ordie("Unabletosetnonblockonsocketn");
$time=time();
//循環的時候每次都減去相應值
while(!@socket_connect($socket,$host,$port))//如果沒有連接上就一直死循環
{
$err=socket_last_error($socket);
if($err==115||$err==114)
{
if((time()-$time)>=$timeout)//每次都需要去判斷一下是否超時了
{
socket_close($socket);
die("Connectiontimedout.n");
}
sleep(1);
continue;
}
die(socket_strerror($err)."n");
}
socket_set_block($this->socket)//還原阻塞模式
ordie("Unabletosetblockonsocketn");
?>
二、升級:使用PHP自帶非同步IO去實現(毫秒級超時)
說明:
非同步IO:非同步IO的概念和同步IO相對。當一個非同步過程調用發出後,調用者不能立刻得到結果。實際處理這個調用的部件在完成後,通過狀態、通知和回調來通知調用者。非同步IO將比特分成小組進行傳送,小組可以是8位的1個字元或更長。發送方可以在任何時刻發送這些比特組,而接收方從不知道它們會在什麼時候到達。
多路復用:復用模型是對多個IO操作進行檢測,返回可操作集合,這樣就可以對其進行操作了。這樣就避免了阻塞IO不能隨時處理各個IO和非阻塞佔用系統資源的確定。
使用socket_select()實現超時
socket_select(...,floor($timeout),ceil($timeout*1000000));
select的特點:能夠設置到微秒級別的超時!
使用socket_select()的超時代碼(需要了解一些非同步IO編程的知識去理解)
復制代碼 代碼如下:
編程 調用類 編程#
<?php
$server=newServer;
$client=newClient;
for(;;){
foreach($select->can_read(0)as$socket){
if($socket==$client->socket){
//NewClientSocket
$select->add(socket_accept($client->socket));
}
else{
//there'ssomethingtoreadon$socket
}
}
}
?>
編程 非同步多路復用IO & 超時連接處理類 編程
<?php
classselect{
var$sockets;
functionselect($sockets){
$this->sockets=array();
foreach($socketsas$socket){
$this->add($socket);
}
}
functionadd($add_socket){
array_push($this->sockets,$add_socket);
}
functionremove($remove_socket){
$sockets=array();
foreach($this->socketsas$socket){
if($remove_socket!=$socket)
$sockets[]=$socket;
}
$this->sockets=$sockets;
}
functioncan_read($timeout){
$read=$this->sockets;
socket_select($read,$write=NULL,$except=NULL,$timeout);
return$read;
}
functioncan_write($timeout){
$write=$this->sockets;
socket_select($read=NULL,$write,$except=NULL,$timeout);
return$write;
}
}
?>
[C&C++中超時實現]
一般在LinuxC/C++中,可以使用:alarm()設置定時器的方式實現秒級超時,或者:select()、poll()、epoll()之類的非同步復用IO實現毫秒級超時。也可以使用二次封裝的非同步io庫(libevent,libev)也能實現。
一、使用alarm中用信號實現超時 (秒級超時)
說明:Linux內核connect超時通常為75秒,我們可以設置更小的時間如10秒來提前從connect中返回。這里用使用信號處理機制,調用alarm,超時後產生SIGALRM信號(也可使用select實現)
用alarym秒級實現connect設置超時代碼示例:
復制代碼 代碼如下:
//信號處理函數
staticvoidconnect_alarm(intsigno)
{
debug_printf("SignalHandler");
return;
}
//alarm超時連接實現
staticvoidconn_alarm()
{
Sigfunc*sigfunc;//現有信號處理函數
sigfunc=signal(SIGALRM,connect_alarm);//建立信號處理函數connect_alarm,(如果有)保存現有的信號處理函數
inttimeout=5;
//設置鬧鍾
if(alarm(timeout)!=0){
//...鬧鍾已經設置處理
}
//進行連接操作
if(connect(m_Socket,(structsockaddr*)&addr,sizeof(addr))<0){
if(errno==EINTR){//如果錯誤號設置為EINTR,說明超時中斷了
debug_printf("Timeout");
⑸ win2008 + wamp正常使用幾個小時後就無法打開PHP網頁
如果你是指電腦無法打開或瀏覽網頁,你可根據以下情況進行排障:
1、寬頻未連接。重新連接寬頻。
2、路由器故障。拆除路由器後,進行寬頻連接試用。
3、偶發性故障,如ADSL斷流,電腦內存數據溢出等。重啟電腦、modem試用。
4、瀏覽器陪搏故障,應用不恰當的代理伺服器。卸載一切瀏覽器插件,恢復IE瀏覽器默認設置試用。去掉代理伺服器設置。重裝瀏覽器程序。
5、IP地址、DNS設置設置不當。一般家庭用戶IP地址設置成自動獲取,重設DNS伺服器地址。
6、殺毒軟體防火牆設置錯誤。臨時關閉殺毒軟體防火牆試用,如果恢復正常,檢查被禁用項目,放行即可。
7、電腦蘆核祥中毒或者被攻擊。升級殺毒軟體至最新版本,打好系統補丁,在安全模式下查殺病毒,如果病毒殺不掉需要重做系統。
8、TCP/IP 出錯。點擊開始--運行--輸入CMD,在Dos提示符下輸入命令「ping 127.0.0.1」(本機循環地址),如果顯示Reply from 127.0.0.1: bytes=?? time=?ms TTL=???,則表示TCP/IP協議運行正常,若顯示Request timed out(超時),重裝該協議。ping本機IP地址。使用ipconfig查看本機IP地址,若通則表明網路適配器工作正常,否則可能是網卡故障。WIN98、2000可用重裝協議。XP、vista、win7需要重做系統。
9、系統文件丟失、操作系統故障。可分析何種故障,可用系統安裝盤恢復,或者重做系統。
10、新裝軟體之間有沖突。最近安裝的程序分析可能引起沖突的軟體,卸載試用。
11、不同的撥號軟體相互干擾。win98 、2000系統只用一個撥號軟體。XP、vista、win7盡量使用自帶撥號程序。
12、多網卡沖突,或者網卡工作不正常。ping本機氏物IP地址。使用ipconfig查看本機IP地址,若通則表明網路適配器工作正常,否則可能是網卡壞。禁用不用的網卡,檢查網卡驅動是否與新裝軟體、新裝驅動有沖突,咨詢客戶是否添加新硬體如果用請拆除臨時新硬體使用。重啟電腦網卡,更改網卡工作速率試用。
13、寬頻信號,樓宇交換機出現故障。撥打寬頻所屬運營商客服熱線進行故障申告。
⑹ TCP協議總結
Transmission Control Protocol,傳輸控制協議,是一種面向連接的、可靠的、基於位元組流的傳輸層通信協議
TCP協議的目的是: 在不可靠傳輸的IP層之上建立一套可靠傳輸的機制。 TCP的可靠只是對於它自身來說的, 甚至是對於socket介面層, 兩個系統就不是可靠的了, 因為發送出去的數據, 沒有確保對方真正的讀到(所以要在業務層做重傳和確認機制)。
可靠傳輸的第一要素是 確認 , 第二要素是 重傳 , 第三要素是 順序 。 任何一個可靠傳輸的系統, 都必須包含這三個要素。 數據校驗 也是必要的。
傳輸是一個廣義的概念, 不局限於狹義的網路傳輸, 應該理解為通信和交互. 任何涉及到通信和交互的東西, 都可以借鑒TCP的思想。無論是在UDP上實現可靠傳輸或者創建自己的通信系統,無論這個系統是以API方式還是服務方式,只要是一個通信系統,就要考慮這三個要素。
SeqNum的增加是和傳輸的位元組數相關的。 上圖中,三次握手後,來了兩個Len:1440的包,而第二個包的SeqNum就成了1441。然後第一個ACK回的是1441(下一個待接收的位元組號),表示第一個1440收到了。
網路上的傳輸是沒有連接的,包括TCP也是一樣的 。而TCP所謂的「連接」,其實只不過是在通訊的雙方維護一個「連接狀態」,讓它看上去好像有連接一樣。所以,TCP的狀態變換是非常重要的。
查看各種狀態的數量
ss -ant | awk '{++s[$1]} END {for(k in s) print k,s[k]}'
通過三次握手完成連接的建立
三次握手的目的是交換通信雙方的初始化序號,以保證應用層接收到的數據不會亂序,所以叫SYN(Synchronize Sequence Numbers)。
ISN是不能hard code的,不然會出問題的。比如:如果連接建好後始終用1來做ISN,如果client發了30個segment過去,但是網路斷了,於是client重連,又用了1做ISN,但是之前連接的那些包到了,於是就被當成了新連接的包,此時,client的Sequence Number可能是3,而Server端認為client端的這個號是30了。全亂了。RFC793中說,ISN會和一個假的時鍾綁在一起,這個時鍾會在每4微秒對ISN做加一操作,直到超過232,又從0開始。這樣,一個ISN的周期大約是4.55個小時。因為,我們假設我們的TCP Segment在網路上的存活時間不會超過Maximum Segment Lifetime(MSL),所以,只要MSL的值小於4.55小時,那麼,我們就不會重用到ISN。
如果Server端接到了Clien發的SYN後回了SYN-ACK,之後Client掉線了,Server端沒有收到Client返回的ACK,那麼,這個連接就處於一個中間狀態,即沒成功,也沒失敗。於是,Server端如果在一定時間內沒有收到的ACK會重發SYN-ACK。在Linux下,默認重試次數為5次,重試的間隔時間從1s開始每次都翻番,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發出後還要等32s都知道第5次也超時了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 26 -1 = 63s,TCP才會斷開這個連接。
客戶端給伺服器發了一個SYN後,就下線了,於是伺服器需要默認等63s才會斷開連接,這樣,攻擊者就可以把伺服器的SYN連接的隊列耗盡,讓正常的連接請求不能處理。
於是,Linux下給了一個叫tcp_syncookies的參數來應對這個事:當SYN隊列滿了後,TCP會通過源地址埠、目標地址埠和時間戳打造出一個特別的Sequence Number發回去(又叫cookie),此時伺服器並沒有保留客戶端的SYN包。如果是攻擊者則不會有響應,如果是正常連接,則會把這個SYN Cookie發回來,然後服務端可以通過cookie建連接(即使你不在SYN隊列中)。
千萬別用tcp_syncookies來處理正常的大負載的連接的情況。因為sync cookies是妥協版的TCP協議,並不嚴謹。應該調整三個TCP參數:tcp_synack_retries減少重試次數,tcp_max_syn_backlog增大SYN連接數,tcp_abort_on_overflow處理不過來乾脆就直接拒絕連接
因為TCP是全雙工的,因此斷開連接需要4次揮手,發送方和接收方都需要發送Fin和Ack。如果兩邊同時斷連接,那就會就進入到CLOSING狀態,然後到達TIME_WAIT狀態。
指的是報文段的最大生存時間,如果報文段在網路中活動了MSL時間,還沒有被接收,那麼會被丟棄。關於MSL的大小,RFC 793協議中給出的建議是兩分鍾,不過實際上不同的操作系統可能有不同的設置,以Linux為例,通常是半分鍾,兩倍的MSL就是一分鍾,也就是60秒
主動關閉的一方會進入TIME_WAIT狀態,並且在此狀態停留兩倍的MSL時長。由於TIME_WAIT的存在,大量短連接會佔有大量的埠,造成無法新建連接。
主動關閉的一方發出 FIN包,被動關閉的一方響應ACK包,此時,被動關閉的一方就進入了CLOSE_WAIT狀態。如果一切正常,稍後被動關閉的一方也會發出FIN包,然後遷移到LAST_ACK狀態。
CLOSE_WAIT狀態在伺服器停留時間很短,如果你發現大量的 CLOSE_WAIT狀態,那麼就意味著被動關閉的一方沒有及時發出FIN包。
TCP要保證所有的數據包都可以到達,所以,必需要有重傳機制。
接收端給發送端的Ack確認只會確認最後一個連續的包 ,比如,發送端發了1,2,3,4,5一共五份數據,接收端收到了1,2,於是回ack 3,然後收到了4(注意此時3沒收到),此時的TCP會怎麼辦?我們要知道,因為正如前面所說的,SeqNum和Ack是以位元組數為單位,所以ack的時候,不能跳著確認,只能確認最大的連續收到的包,不然,發送端就以為之前的都收到了
但總體來說都不好。因為都在等timeout,timeout可能會很長
不以時間驅動,而以數據驅動重傳
如果包沒有連續到達,就ack最後那個可能被丟了的包,如果發送方連續收到3次相同的ack,就重傳
Selective Acknowledgment, 需要在TCP頭里加一個SACK的東西,ACK還是Fast Retransmit的ACK,SACK則是匯報收到的數據碎版,在發送端就可以根據回傳的SACK來知道哪些數據到了,哪些沒有收到
重復收到數據的問題,使用了SACK來告訴發送方有哪些數據被重復接收了
經典演算法:Karn/Partridge演算法,Jacobson/Karels演算法
TCP必需要知道網路實際的數據處理帶寬或是數據處理速度,這樣才不會引起網路擁塞,導致丟包
Advertised-Window :接收端告訴發送端自己還有多少緩沖區可以接收數據。於是發送端就可以根據這個接收端的處理能力來發送數據,而不會導致接收端處理不過來
接收端LastByteRead指向了TCP緩沖區中讀到的位置,NextByteExpected指向的地方是收到的連續包的最後一個位置,LastByteRcved指向的是收到的包的最後一個位置,我們可以看到中間有些數據還沒有到達,所以有數據空白區。
發送端的LastByteAcked指向了被接收端Ack過的位置(表示成功發送確認),LastByteSent表示發出去了,但還沒有收到成功確認的Ack,LastByteWritten指向的是上層應用正在寫的地方。
接收端在給發送端回ACK中會匯報自己的AdvertisedWindow = MaxRcvBuffer – LastByteRcvd – 1;
收到36的ack,並發出了46-51的位元組
如果Window變成0了,發送端就不發數據了
如果發送端不發數據了,接收方一會兒Window size 可用了,怎麼通知發送端呢:TCP使用了Zero Window Probe技術,縮寫為ZWP,也就是說,發送端在窗口變成0後,會發ZWP的包給接收方,讓接收方來ack他的Window尺寸,一般這個值會設置成3次,每次大約30-60秒。如果3次過後還是0的話,有的TCP實現就會發RST把鏈接斷了。
如果你的網路包可以塞滿MTU,那麼你可以用滿整個帶寬,如果不能,那麼你就會浪費帶寬。避免對小的window size做出響應,直到有足夠大的window size再響應。
如果這個問題是由Receiver端引起的,那麼就會使用David D Clark』s 方案。在receiver端,如果收到的數據導致window size小於某個值,可以直接ack(0)回sender,這樣就把window給關閉了,也阻止了sender再發數據過來,等到receiver端處理了一些數據後windows size大於等於了MSS,或者receiver buffer有一半為空,就可以把window打開讓send 發送數據過來。
如果這個問題是由Sender端引起的,那麼就會使用著名的 Nagle』s algorithm。這個演算法的思路也是延時處理,他有兩個主要的條件:1)要等到 Window Size >= MSS 或是 Data Size >= MSS,2)等待時間或是超時200ms,這兩個條件有一個滿足,他才會發數據,否則就是在攢數據。
TCP_CORK是禁止小包發送,而Nagle演算法沒有禁止小包發送,只是禁止了大量的小包發送
TCP不是一個自私的協議,當擁塞發生的時候,要做自我犧牲
擁塞控制的論文請參看 《Congestion Avoidance and Control》
主要演算法有:慢啟動,擁塞避免,擁塞發生,快速恢復,TCP New Reno,FACK演算法,TCP Vegas擁塞控制演算法
TCP網路協議及其思想的應用
TCP 的那些事兒(上)
TCP 的那些事兒(下)
tcp為什麼是三次握手,為什麼不是兩次或四次?
記一次TIME_WAIT網路故障
再敘TIME_WAIT
tcp_tw_recycle和tcp_timestamps導致connect失敗問題
tcp短連接TIME_WAIT問題解決方法大全(1)- 高屋建瓴
tcp短連接TIME_WAIT問題解決方法大全(2)- SO_LINGER
tcp短連接TIME_WAIT問題解決方法大全(3)- tcp_tw_recycle
tcp短連接TIME_WAIT問題解決方法大全(4)- tcp_tw_reuse
tcp短連接TIME_WAIT問題解決方法大全(5)- tcp_max_tw_buckets
TCP的TIME_WAIT快速回收與重用
淺談CLOSE_WAIT
又見CLOSE_WAIT
PHP升級導致系統負載過高問題分析
Coping with the TCP TIME-WAIT state on busy Linux servers
⑺ 關於php中socket的問題:
這是socket的服務端的代碼,監聽的ip地址是192.168.168.121,埠號為8528
請檢查以下幾點
這個ip是不是代碼所在伺服器的ip,一般監測內網ip,如127.0.0.1
埠號是否被使用,可以使用cmd命令 netstat -ano|findstr 8528 查找埠號為8528的埠使用情況
如果要給在公網上使用,請使用公網ip,這樣可以外網使用
如果代碼不報錯可以試下telnet下你的埠號,看是否可以使用
如 telnet 127.0.0.1 8528
解決方案
查看你電腦的ip地址,把上面代碼里「$address = '192.168.168.121';」這個ip地址換成「$address = '127.0.0.1';」或者你電腦的ip地址,再試試。
(ip地址改成127.0.0.1後,這段代碼在我電腦上可以使用)
⑻ php(5.2.3)無法連接mysql(5.5.22),錯誤:Can't create TCP/IP socket (10106) 平台為win7和iis
php的內部原因的,php的版本不一樣相應的一些褲態褲文件的配置和路徑什麼胡簡的都不行同的,要修改的話,閉孝去php.ini中改改吧!