讓我們得到一些基本的先降:
每個插座具有接收和發送緩衝區。當網絡硬件發信號通知新數據包和到達接收緩衝區已滿時,數據包將被丟棄。緩衝區大小通過SO_RCVBUF
和SO_SNDBUF
插座選項進行控制,請參見setsockopt(3)
。操作系統設置了一些默認設置(並且有/etc/sysctl.conf
文件)。這是一個BSD系統上:
~$ sysctl -a|grep space
net.inet.tcp.recvspace=16384
net.inet.tcp.sendspace=16384
net.inet.udp.recvspace=41600
net.inet.udp.sendspace=9216
TCP和UDP之間的區別在於,前者以數據排序和丟棄的數據包的重傳,再加上流量控制的護理(慢讀者減慢快作家),而後者則沒有。
所以是的,使用UDP傳輸文件不是最好的,,但可行,選項。人們必須重新創建TCP的一部分,並權衡重新發明對TCP的開銷。再一次,普遍的看法是,UDP最適合於可以容忍某些分組重排序/丟失的應用程序(例如音頻/視頻流)。
然後有一個錯誤的觀點,即每個套接字都需要一個單獨的線程來發送/接收數據,這遠非事實。許多優秀的高性能網絡應用程序都是在沒有線程的情況下編寫的,但使用了非阻塞套接字和一些輪詢機制(請參閱select(2)
,poll(2)
,epoll(7)
)。
爲了這個問題本身:
是,如果應用程序是太忙,無法保持足夠的可用空間,插座內核可能會丟棄數據包接收緩衝區。但是由於每個套接字都有自己的特性,控制和數據流的分離將會有所幫助。就個人而言,我會去做一個簡單的TCP服務器設置 - 偵聽端口,接受每個客戶端的連接,在TCP流上實現一個有意義的協議。我同意玩UDP和低級別協議狀態機非常有趣,但已經完成了,幾十年的研究進入了調整TCP性能。最重要的是你的應用程序的可靠性(第一)和性能(第二)。
希望這會有所幫助。
尼古拉最好的回答。我昨天實際上在想,要走的路將是TCP和NIO。我的設備不能處理太多的線程,並且它會自動清除。有很多傳入的請求。 – Gubatron 2010-04-05 16:44:14
你知道你可以*接受*答案,對嗎? :) – 2010-04-05 17:58:35
只有當數據需要實時更新並且不能承受重傳費用時,UDP纔有用。這種連接的例子包括流視頻/音樂,延遲真正重要的實時遊戲,或者文件傳輸(FTP),無論如何,接收端都要通過CRC校驗驗證數據塊。 – 2010-06-23 06:43:10