1. 程式人生 > >socket accept後的fd是否佔用新埠

socket accept後的fd是否佔用新埠

今天小組討論了下自動化部署的架構與實現。在討論推送配置的時候,我發現了一個問題,這也讓我知道了我以前一直忽略的一個東西。

很多人socket程式設計很熟悉,但是能知道下面細節的人就不是那麼多了。以前就想讀tcp ip協議詳解,可惜那時候的功力還沒到,看來等有時間還是得細細品讀。

大家都很熟悉,在server端程式設計,首先得建立一個socket並bind一個地址,然後進行listen和accept,當客戶端有連線的時候,accept會返回一個fd,代表了與客戶端的連線,我們可以通過這個fd來跟對應的client端進行io通訊,也可以捕捉到斷開的事件。

問題就在上面accept的fd上面。我以前的理解一直以為這個fd佔用了一個新的埠號,並且這個佔用的埠號與client一致,通過相同的埠號進行傳輸。當時也沒有懷疑正確與否,現在想來,真是錯誤百出。

首先,socketlisten後,是肯定佔用了對應的埠號的,任何別的嘗試使用該埠的操作肯定會報錯,這是毋庸置疑的。accept的新的fd,佔不佔用新的埠號呢?看到這裡大家肯定也都明白了,是不佔用的。那不佔用,肯定和listen的埠一樣啊?不是上面說了一個埠只能使用一次嗎?

這裡就引出了socket的底層結構。區別兩個socket是否一致,需要5元組來區別,分別是本機的ip 本機的埠 目標機的ip 目標機的埠 還有一個是協議。通過這些可以唯一的區別socket,當這些一致,那麼這兩個socket是一樣的。系統提供的api,比如bind listen connect,其實都隱藏了對socket元組資訊的寫入。

再談談上述的問題,在accept一個新的連線後,其實fd的確是新的fd,但是它的本機ip port是和listen的一樣的,而不同的client的fd之間的區別,就是不同的目標機的ip port資訊。

這個問題解決了,那麼我們再梳理一下結構。為何系統要劃分埠號?其實埠這個概念,是在tcp這一層,即傳輸層實現的東西,為上層應用層提供支援。當應用層通過socket send資料的時候,tcp層會根據目標主機的ip port等資訊進行資料包的進一步封裝,然後將其交給ip層來進行網路傳輸,ip層則根據目標ip地址來將其再次封裝然後最終交給物理層進行傳輸。

而對於client來說,首先ip層會收到這個資料,然後根據頭部資訊中的協議來交給不同的協議來進行處理。向上交給tcp層之後,tcp層會從頭部資料中獲取到埠號資訊,到這一步其實已經可以唯一確定是哪個程序的資料了,通過埠號查到程序,並通知程序進行處理。這樣整個通訊就走通了。

上面也談到了,每一個socket都有一個local address和remote address,而對應的遠端client的socket,也有一個local address和remote address,有意思的是,他們是互相相反的關係。其實想想也是,tcp向下傳輸的時候,需要給ip層傳入remote ip,用於路由傳輸,而remote port,則會附加到資料頭部中,因為這個remote port是需要給client來區分程序的。client收到了這個資料包後,根據server傳入的port,則可以唯一的區分是哪個程序的資料包。而client傳送的資料,則會帶入client這個socket的remote port,然後最終資料會傳輸給server listen 的那個socket。tcp資料頭中還會有client的local address的資訊,所以傳送到server監聽的socket上後,可以通過client的ip port來區分是哪一個client傳送的資料,之後的就交由應用程式來處理了。

上面的總結也就是每個socket都是有著通過local address來與remote address相連的意思,也就是兩個埠號是可以不一樣的。

當然上面的只是記錄下今天的想法,只是感覺有必要去讀下tcp ip協議了,以前讀著摸不著頭腦,現在讀著卻有著原來是這樣啊的感慨。

相關推薦

socket acceptfd是否佔用

今天小組討論了下自動化部署的架構與實現。在討論推送配置的時候,我發現了一個問題,這也讓我知道了我以前一直忽略的一個東西。 很多人socket程式設計很熟悉,但是能知道下面細節的人就不是那麼多了。以前就想讀tcp ip協議詳解,可惜那時候的功力還沒到,看來等有時間還是得細細

Socket關閉端口仍然佔用導致無法建立的連線

目的:研究生高階計算機網路課程大作業--實現DV演算法的router編寫(JAVA) 問題描述:       使用UDP協議進行通訊,好不容易使執行緒Thread安全地關閉,卻無法再次獲取 同一個(IP,Port) 上的連線。       關於執行緒的安全終止這裡再說兩

私人影院火爆快速死亡?

廣電總局 投影幕布 朋友聚會 創業者 電影院 在這個互聯網無孔不入的快節奏時代,大眾不僅需要更多的娛樂新方式,而且還必須能夠有更好的隱私性和舒適性。面對這種新需求,為特定群體打造的娛樂方式層出不窮地出現。迷你KTV、私人影院等,都是其中的代表。而私人影院在國內範圍內的火爆之勢,也讓其成為眾

Python中網絡編程對socket accept函數的理解

可以關閉 分享圖片 pos pytho clas blog 服務 ket src 在服務器端,socket()返回的套接字用於監聽(listen)和接受(accept),這個套接字不能用於與客戶端之間發送和接收數據。 accept()接受一個客戶端的連接請求,並返回一

【TED】我們成年依然能生成的腦細胞

html 飲食 增長 癌癥 學習 open PE 想要 .com 觀看地址:http://open.163.com/movie/2015/12/V/N/MB6IJ08AU_MB729EVVN.html 海馬體能生成新的神經元,每天約700個,近50歲時,大腦的神經元結構來自

端修改配置文件,前端刷頁面--搭配鑒權

ebs 保存 用戶體驗 不同 請求 blank 如果 AR 客戶   背景:   一個PC端的網站,用戶登錄後,網站顯示的內容會根據該用戶的在該網站中所設置的配置而有所不同,也就是說,每個用戶在配置頁面開啟了和配置了不同的配置項,那麽在首次訪問該網站的首頁時,顯示的內容也會

confluence中org.apache.tomcat.util.net.NioEndpoint$Acceptor.run Socket accept failed的解決方法

load cal internal works dac shu per ots star confluence中org.apache.tomcat.util.net.NioEndpoint$Acceptor.run Socket accept failed的解決方法 1.

《21天學通C#》變數使用前需要宣告和賦值,賦值可以重新賦的值

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace 變數宣告賦值使用{ class Program { static

Windows查詢佔用8080的程序號並殺死程序

首先查詢到佔用8080埠的程序號PID是多少 CMD>netstat -ano | findstr 8080 這個命令輸出的最後一列表示佔用8080埠的程序號是多少,假設為1234 kill掉這個程序 CMD>

解決vue單頁面跳轉返回頁面不刷的問題

() function -h null 頁面 margin 我們 col cati 一、問題:在vue項目中通過location.href跳轉到第三方頁面,然後點擊瀏覽器返回按鈕回到自己的頁面,用nginx起服務頁面不刷新,在用node起服務中頁面是正常刷新的; 二、產生該

通過程序PID找到其佔用

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

window 中殺死佔用某個號的程序

第一步,開啟cmd命令視窗,輸入命令,根據埠號查詢對應的程序號 netstat -ano | findstr 8080 //檢視8080埠 netstat -ano | findstr 80 //列出程序及其佔用的埠,並且包含80 發現8080埠被PID(程序號)為952的程

22年的甲骨文生涯 谷歌雲主管面臨一場文化衝突

@央廣軍事11月10日訊息,2018中國航展上首次公開展出的“瞭望者Ⅱ”察打一體導彈無人艇,是剛剛成功進行首發導彈飛行試驗命中靶心的實艇,試驗成功後隨即吊裝到展位與公眾見面。據媒體此前報道,該艇是中國第一艘導彈無人艇,也是繼以色列拉斐爾海上騎士後全球第二個成功發射導彈的無人艇,填補了國內導彈無人艇這一技術空白

轉 zookeeper啟動為什麼佔用8080,修改哪個配置檔案可以改變

在zookeeper啟動的時候,看列印資訊顯示會啟動jetty,啟動一個adminServer on port 8080;我不想他佔用8080埠,請問哪位大神能告訴我哪個配置檔案可以修改埠?  是我下載的zookeeper版本不對,我下載的是最新版的alpha版本,裡面有jetty的啟動;

centos 7 安裝獨立環境 tcp6佔用80解決方法

重啟apache時提示錯誤(並且無法殺死程序): 輸入netstat -lnp | grep 80;發現是tcp6佔用 解決方法: 1、開啟/etc/sysctl.conf 2、新增如下三條設定      net.ipv6.conf.all.disable_ip

controller在連線加壓機時連線失敗,重啟加壓機也不好使,怎麼解決?怎麼檢視被佔用號及解除佔用

這個問題的背景是,我在做壓測的時候,需要用的是阿里雲的虛擬機器充當加壓機,通過loadrunner的controller進行連線時,經常出現失敗的情況,如圖所示: controller呼叫加壓機,是通過54345埠,出現這種情況連線失敗的情況,通常是本地與加壓機的54345埠不通 可以通過t

Linux工作筆記028---Centos7.3 檢視tomcat所佔用

netstat命令用來列印Linux中網路系統的狀態資訊,可讓你得知整個Linux系統的網路情況。 語法 netstat(選項) 選項 -a或--all:顯示所有連線中的Socket; -A<網路型別>或--<網路型別>:列出該網路型別連線中

Linux檢視端口占用情況,並強制釋放佔用

1.查詢被佔用的埠 netstat -tln netstat -tln | grep 8080  netstat -tln 檢視埠使用情況,而netstat -tln | grep 8080則是隻檢視埠8080的使用情況 2.檢視埠屬於哪個程式?埠被哪個程序佔

解決Windows Server 2008 System程序佔用80問題

解決Windows Server 2008 System程序佔用80埠 輸入netstat -ano|findstr"80" 可以看到80埠被PID4佔用 輸入tasklist|findstr"4" 可以看到pid 4 的被 System 佔用 該程序是Http.sys。它是http API的驅動元

Windows中殺死佔用某個的程序

第一步 根據埠號查詢對應的程序號 netstat -ano | findstr 80 //列出程序極其佔用的埠,且包含 80 1 結果如下:  發現 8080 埠被 PID(程序號)為 9268 的程序佔用。 第二步 據程序號尋找程序名稱 tasklist | fi