淺談linux中的網(wǎng)絡(luò)

linux網(wǎng)絡(luò)棧和tcp/ip

簡(jiǎn)單的來說扒寄,socket就是對(duì)tcp/ip的api接口毫别。通過socket接口组贺,兩個(gè)主機(jī)建立連接后直接通過recv()和send()即可以完成兩個(gè)主機(jī)之間的通信泡躯。

但是有沒有想過儿普,在TCP/IP中崎逃,在鏈路層,我們需要對(duì)數(shù)據(jù)包添加幀頭(MAC地址信息等)眉孩,IP層个绍,我們又要為數(shù)據(jù)包添加IP頭(ip地址)勒葱,在傳輸層,我們又需要添加端口信息等巴柿。而且其中還有一些差錯(cuò)校驗(yàn)等工作我們都沒有做凛虽。但是,事實(shí)上广恢,在每一次包傳輸?shù)倪^程中凯旋,linux網(wǎng)絡(luò)協(xié)議棧都完成了對(duì)這些工作。而我們只需要調(diào)用內(nèi)核暴露出來的系統(tǒng)調(diào)用(socket)就可以了

如下圖所示袁波,網(wǎng)絡(luò)包從網(wǎng)卡傳遞到應(yīng)用層可以分為如下幾個(gè)步驟:

  1. 網(wǎng)卡接受到數(shù)據(jù)包后瓦阐,將數(shù)據(jù)包存放到包接受隊(duì)列中去,并且發(fā)出硬中斷信號(hào)
  2. 硬中斷處理程序?qū)?shù)據(jù)包篷牌,存放到sk_buff緩沖區(qū)中,并且發(fā)出軟中斷信息
  3. 內(nèi)核收到軟中斷后踏幻,將sk_buff中取出傳遞給linux網(wǎng)絡(luò)協(xié)議棧
  4. 經(jīng)過網(wǎng)絡(luò)協(xié)議棧的一些列的處理枷颊,將數(shù)據(jù)存放到了socket緩存中
  5. 應(yīng)用程序通過調(diào)用socket接口從socket緩存中取出數(shù)據(jù)
network1.png

小實(shí)驗(yàn)

# 一臺(tái)服務(wù)端server,兩個(gè)客戶端c1, c2该面,os-centos7
# server
[root@master ~]# python
Python 2.7.5 (default, Apr  9 2019, 14:30:50) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket()
>>> s.bind(("x.x.x.x", 20000))  # 綁定端口
>>> s.listen(10)  # 監(jiān)聽該端口
# 在服務(wù)端另外打開一個(gè)端口夭苗,輸入以下命令
# netstat -tnlp | grep 20000
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python
# 發(fā)現(xiàn)server端開始監(jiān)聽20000端口,從recv-q和send-q為0可以看出此時(shí)還沒有客戶發(fā)起連接請(qǐng)求
# 注:在listen狀態(tài)下recv-q表示半連接狀態(tài)的個(gè)數(shù)隔缀,即客戶端發(fā)送了連接請(qǐng)求题造,但服務(wù)端還沒有發(fā)ack報(bào)文
# 打開一個(gè)c1客戶端
>>> import socket
>>> s = socket.socket()
>>> s.connect(("x.x.x.x", 20000))
# 在c1客戶端中發(fā)送連接請(qǐng)求
# 回到server打開另一終端,輸入如下命令
[root@master ~]# netstat -atnp | grep 20000
tcp        1      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:39332    ESTABLISHED -  
# 再打開另外一個(gè)客戶端c2
>>> import socket
>>> s = socket.socket()
>>> s.connect(('x.x.x.x', 20000))
# 回到server中猾瘸,輸入如下命令
# netstat -atnp | grep 20000
tcp        2      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:47890    ESTABLISHED -                   
tcp        0      0 x.x.x.x:20000    x.x.x.x:39332    ESTABLISHED -
# 此時(shí)發(fā)現(xiàn)recv-q中字段為2界赔,表示半連接的個(gè)數(shù),即表示客戶端發(fā)送了連接請(qǐng)求牵触,但還沒得到服務(wù)端的ack報(bào)文淮悼。半連接狀態(tài)在linux也有也顯示,但看不到對(duì)應(yīng)的進(jìn)程(對(duì)比下面建立時(shí)的區(qū)別)

# 回到server中的python終端窗口
>>> import socket
>>> s = socket.socket()
>>> s.bind(("x.x.x.x", 20000))
>>> s.listen(10)
>>> c1, addr = s.accept()  # 從半連接隊(duì)中揽思,選擇一個(gè)半連接袜腥,發(fā)送確定幀,形成連接
>>> c2, addr2 = s.accept()
# 回到server中終端窗口
[root@master ~]# netstat -atnp | grep 20000
tcp        0      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:47890    ESTABLISHED 172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:39332    ESTABLISHED 172870/python
# 發(fā)現(xiàn)監(jiān)聽狀態(tài)的端口的recv-q字段變?yōu)?了钉汗,并且下方顯示成功建立的連接羹令。
# 去其中一個(gè)client發(fā)送一下數(shù)據(jù)
>>> import socket
>>> s = socket.socket()
>>> s.connect(("x.x.x.x", 20000))
>>> s.send('today is a good day')
19
# 回到master的termal
[root@master ~]# netstat -atnp | grep 20000
tcp        0      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:47890    ESTABLISHED 172870/python       
tcp       19      0 x.x.x.x:20000    x.x.x.x:39332    ESTABLISHED 172870/python 
# 注意,在establish狀態(tài)時(shí)损痰,recv-q表示的接收緩沖去中還有多少數(shù)據(jù)沒有被取走福侈,發(fā)現(xiàn)正好是上面輸入的19個(gè)字符還沒有被取走
# 回到master中python終端
>>> import socket
>>> s = socket.socket()
>>> s.bind(("x.x.x.x", 20000))
>>> s.listen(10)
>>> c1, addr = s.accept()
>>> c2, addr2 = s.accept()
>>> c1.recv(5)   # 從接受隊(duì)列中取走五個(gè)字符的數(shù)據(jù)
'today'
# 回到server的終端
[root@master ~]# netstat -atnp | grep 20000
tcp        0      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:47890    ESTABLISHED 172870/python       
tcp       14      0 x.x.x.x:20000    x.x.x.x:39332    ESTABLISHED 172870/python
# 發(fā)現(xiàn)19變成14了,正好符合實(shí)驗(yàn)預(yù)期

#回到一個(gè)client終端徐钠,關(guān)閉一端的連接
>>> s = socket.socket()
>>> s.connect(("x.x.x.x", 20000))
>>> s.send('today is a good day')
19
>>> s.close()
# 回到server終端
[root@master ~]# netstat -atnp | grep 20000
tcp        0      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:47890    ESTABLISHED 172870/python       
tcp        14      0 x.x.x.x:20000    x.x.x.x:39332    CLOSE_WAIT  172870/python 
# 符合tcp的要求癌刽,關(guān)閉tcp連接時(shí),需要雙方都要關(guān)閉,此時(shí)僅客戶端關(guān)閉了显拜,也要到server端去關(guān)閉連接
# 回到server終端
>>> import socket
>>> s = socket.socket()
>>> s.bind(("x.x.x.x", 20000))
>>> s.listen(10)
>>> c1, addr = s.accept()
>>> c2, addr2 = s.accept()
>>> c1.recv(5)
'today'
>>> c1.close()
# 回到server終端
[root@master ~]# netstat -atnp | grep 20000
tcp        0      0 x.x.x.x:20000    0.0.0.0:*               LISTEN      172870/python       
tcp        0      0 x.x.x.x:20000    x.x.x.x:47890    ESTABLISHED 172870/python
# 連接完全關(guān)閉了

linux常見網(wǎng)絡(luò)命令

  1. nslookup: 查看域名的ip地址
  2. /etc/resolv.conf: 設(shè)置DNS服務(wù)器
  3. time:查看一個(gè)命令的運(yùn)行時(shí)間
  4. wrk和ab: http壓力測(cè)試工具
  5. sar: 查看網(wǎng)絡(luò)每秒的傳輸數(shù)據(jù)
  6. /etc/sysctl.conf: 配置linux網(wǎng)絡(luò)協(xié)議棧參數(shù)(sysctl -p 是配置生效)
配置內(nèi)容 配置描述
net.ipv4.ip_forward linux內(nèi)核是否可以轉(zhuǎn)發(fā)數(shù)據(jù)包
net.ipv4.tcp_max_sys_backlog tcp半連接最大數(shù)目
net.ipv4.tcp_xx 一些列和tcp相關(guān)的參數(shù)
net.ipv4.udp_xx 一些列和udp相關(guān)的參數(shù)
net.core.rmem.max 套接字接受緩沖區(qū)大小
net.core.wmem_max 套接字發(fā)送緩沖區(qū)大小
  1. iptables: 數(shù)據(jù)包轉(zhuǎn)發(fā)的控制
  2. ip: 查看ip地址情況
  3. ifconfig: 查看網(wǎng)卡及ip地址衡奥,還有網(wǎng)絡(luò)接受/發(fā)送包的個(gè)數(shù)和字節(jié)數(shù)

小實(shí)驗(yàn)

# cat /etc/resolv.conf    # 查看系統(tǒng)配置的DNS服務(wù)器
# Generated by NetworkManager
nameserver 202.115.32.36
nameserver 8.8.8.8 

[root@master ~]# time nslookup www.baidu.com
Server:     202.115.32.36    # DNS服務(wù)器地址
Address:    202.115.32.36#53 # DNS服務(wù)器地址及其監(jiān)聽的端口

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com.
Name:   www.a.shifen.com   # 域名
Address: 182.61.200.6  # 地址
Name:   www.a.shifen.com
Address: 182.61.200.7

real    0m0.011s   # time命令所展示的時(shí)間,實(shí)際用了0.011秒
user    0m0.005s
sys 0m0.006s
# 換一個(gè)DNS服務(wù)器
[root@master ~]# echo "nameserver 8.8.8.8" > /etc/resolv.conf && cat /etc/resolv.conf
nameserver 8.8.8.8  

[root@master ~]# time nslookup www.baidu.com
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com.
www.a.shifen.com    canonical name = www.wshifen.com.
Name:   www.wshifen.com
Address: 103.235.46.39


real    0m0.290s   # 剛剛是0.011秒远荠,現(xiàn)在是0.29秒啊矮固,慢了好多啊譬淳!還是換回來把
user    0m0.008s
sys 0m0.007s

# echo "nameserver 202.115.32.36" > /etc/resolv.conf
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末档址,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子邻梆,更是在濱河造成了極大的恐慌守伸,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浦妄,死亡現(xiàn)場(chǎng)離奇詭異尼摹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)剂娄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門蠢涝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人阅懦,你說我怎么就攤上這事和二。” “怎么了耳胎?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵惯吕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我场晶,道長(zhǎng)混埠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任诗轻,我火速辦了婚禮钳宪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扳炬。我一直安慰自己吏颖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布恨樟。 她就那樣靜靜地躺著半醉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劝术。 梳的紋絲不亂的頭發(fā)上缩多,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天呆奕,我揣著相機(jī)與錄音,去河邊找鬼衬吆。 笑死梁钾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逊抡。 我是一名探鬼主播姆泻,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼冒嫡!你這毒婦竟也來了拇勃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤孝凌,失蹤者是張志新(化名)和其女友劉穎方咆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胎许,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡峻呛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辜窑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寨躁,死狀恐怖穆碎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情职恳,我是刑警寧澤所禀,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站放钦,受9級(jí)特大地震影響色徘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜操禀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一褂策、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颓屑,春花似錦斤寂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至器腋,卻和暖如春溪猿,著一層夾襖步出監(jiān)牢的瞬間钩杰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工诊县, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讲弄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓翎冲,卻偏偏與公主長(zhǎng)得像垂睬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抗悍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容