Python Socket網絡編程(二)局域網內和局域網與廣域網的持續通信

前言

       本系列博客是筆者學習Python Socket的過程筆記第二篇,目的在於記錄。其中的解釋都爲自己的見解,僅供參考,如有錯誤,還望指出。本篇博客是對Python Socket的局域網內兩臺設備之間的通信,和局域網和廣域網(通常是指我們購買的服務器)之間的通信區別,在上一篇博客中,記錄了socket模塊和初步實現了一臺設備(電腦)中的不同進程之間的通信,有興趣的請前往上一篇博客Python Socket網絡編程(一)初識Socket和Socket初步使用。
       這一節的內容不算多,但是我還是單獨列出來,原因在於這一塊非常重要,其中還有一塊關於IP的知識必須掌握才能對網絡編程有幫助。

IP地址

  • 簡介

       網絡之間互連的協議(IP)是Internet Protocol的外語縮寫。IP協議中一個非常重要的內容,那就是給因特網上的每臺計算機和其它設備都規定了一種地址,叫做“IP 地址”。由於有這種地址,才能對網絡上這麼多設備進行區分,並且根據某一個IP就能找到一個唯一的設備。但是IP地址也是有區分的,廣義上分爲私有IP地址(保留IP地址)和公有IP地址(固定IP地址)。

  • 公有IP

       公有IP地址是由INIC(Internet Network Information Center 因特網信息中心)負責。這些IP地址分配給向INIC提出申請併成功註冊的組織機構。通過公有IP地址能直接訪問因特網,當然公有IP是要錢的。

  • 私有IP

       隨着網絡的發展,爲節省可分配的註冊IP地址,有一組IP地址被拿出來專門用於私有IP網絡,稱爲私有IP地址。私有IP地址範圍:
       A類: 10.0.0.0~10.255.255.255
       B類:172.16.0.0~172.31.255.255
       C類:192.168.0.0~192.168.255.255
       這些地址是不會被Internet分配的,它們在Internet上也不會被路由,雖然它們不能直接和Internet網連接,但通過技術手段仍舊可以和 Internet通訊(NAT技術)。公網IP是直接與英特網連接可以直接訪問網絡(上網),而私有IP地址則是在局域網中使用的IP地址,私有IP是不能直接上網的(無法直接和公網通信),當私有網絡內的主機要與位於公網上的主機進行通訊時必須經過地址轉換,將其私有地址轉換爲合法公網地址才能對外訪問。也就是要使用NAT-Network Address Translation 網絡地址轉換技術。
       那麼平時我們的電腦是如何上網的呢?比如我們辦理了電信寬帶,拉一根網線連接到我們的電腦,我們的電腦就能上網了。實質上此時我們的電腦是一個私有IP,電信那邊購買了一個公有IP,我們電腦和電信的公有IP之間有一個NAT技術設備,也就是說我們能上網是通過電信的公有IP實現的。
       如果在家安裝了路由器我們的多臺電腦連接在這個路由器上,那麼這些電腦直接就構成了局域網,在這幾臺電腦上可以直接進行局域網的通信。但是你家裏構成的局域網和公司的局域網是不能通過局域網通信的。

       在這裏記錄私有IP和公有IP的原因在於socket網絡通信需要區別,以便我們知道哪些IP之間是不能通信的,哪些IP之間是可以通信的。從上述原理我們就知道同一個局域網內的設備A和設備A,設備A和設備B,廣域網內的設備A和設備B可以實現雙向連接通信,局域網的設備A和廣域網的設備B可以單向連接(只能由局域網去連接廣域網,也就是局域網是客戶端,廣域網是服務端;因爲廣域網的IP是固定且唯一的,局域網連接網絡通過指定這個公有IP就能找到這臺計算機,找的過程是局域網連接電信網絡,通過NAT技術將這個局域網私有IP轉換爲公有IP然後再去和指定的公有IP通信,這樣就可以找到指定的公有IP,相反私有IP是不能被公有IP找到的)通信。不同局域網之間的設備不能通信。

局域網之間網絡通信

  • 前提

       在上一篇博客中實現的是本機的不同進程的通信,這裏要實現同一局域網內兩臺電腦的通信,我這測試的兩臺電腦IP分別爲A(Ubuntu16.04):192.168.27.165和B(Windows10):192.168.27.238,我們如何知道兩臺電腦是否是同一局域網呢。Windows電腦按win+r輸入cmd打開cmd命令控制檯,輸入命令ping 192.168.27.165(我的B電腦是Windows的,我用它去ping我的A電腦IP,能ping通則說明使用socket電腦B能連接上A,也就是A可以運行服務器程序,B運行客戶端程序去連接A,如果在B上也能ping通A則說明AB都能做服務端和客戶端);Ubuntu系統ctr+alt+t打開命令行,輸入命令ping 192.168.27.238,兩邊都能ping通則說明在一個局域網上。

       我這裏隨便選了B作爲服務器端,要想A連接上B電腦建立通信,那麼我們需要先將B的防火牆關掉。

  • 功能描述

       由於要實現同一局域網的兩臺設備的持續通信,找一個設備做服務端,建立socket,監聽B機IP的6688端口等待客戶端來連接,一旦有一個客戶端來連接了就打印連接信息,然後循環等待連接的客戶端發送數據,接收到客戶端傳來的數據後,就反饋給客戶端收到信息了,直至接收到quit信息才退出循環結束連接;客戶端程序先建立socket套接字,然後去連接B機的IP和6688端口進程,連接成功後循環等待控制檯輸入數據,接受到輸入的數據後發送到服務端,然後結束連接。

  • 源碼

       在B(服務端)新建一個server.py文件,然後運行程序,內容如下:

import socket


# 創建一個socket套接字,該套接字還沒有建立連接
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定監聽端口,這裏必須填本機的IP192.168.27.238,localhost和127.0.0.1是本機之間的進程通信使用的
server.bind(('192.168.27.238', 6688))
# 開始監聽,並設置最大連接數
server.listen(5)

print(u'waiting for connect...')
# 等待連接,一旦有客戶端連接後,返回一個建立了連接後的套接字和連接的客戶端的IP和端口元組
connect, (host, port) = server.accept()
print(u'the client %s:%s has connected.' % (host, port))

while True:
    # 接受客戶端的數據
    data = connect.recv(1024)
    # 如果接受到客戶端要quit就結束循環
    if data == b'quit' or data == b'':
        print(b'the client has quit.')
        break
    else:
        # 發送數據給客戶端
        connect.sendall(b'your words has received.')
        print(b'the client say:' + data)

# 結束socket
server.close()

       同時在A(客戶端)新建一個client.py文件,然後運行程序,內容如下:

import socket


# 創建一個socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 主動去連接局域網內IP爲192.168.27.238,端口爲6688的進程
client.connect(('192.168.27.238', 6688))

while True:
    # 接受控制檯的輸入
    data = input()
    # 對數據進行編碼格式轉換,不然報錯
    data = data.encode('utf-8')
    # 如果輸入quit則退出連接
    if data == b'quit':
        print(b'connect quit.')
        break
    else:
        # 發送數據
        client.sendall(data)
        # 接收服務端的反饋數據
        rec_data = client.recv(1024)
        print(b'form server receive:' + rec_data)

# 發送數據告訴服務器退出連接
client.sendall(b'quit')
client.close()
  • 運行結果

在這裏插入圖片描述
在這裏插入圖片描述

       上面第一個截圖是客戶端(hello、nice to meet you.、I wanna quit.、quit都是輸入的數據),第二個是服務端截圖。

局域網與廣域網網絡通信

  • 前提

       實現局域網到廣域網的通信,首先需要一臺連網的本地計算機和一個服務器(比如購買的阿里雲服務器,必須是連接英特網的)。只要本地的計算機能ping通服務器的IP就行了(服務器是無法ping通本地的計算機的,原因前面已經介紹)。

  • 源碼

       由於局域網和廣域網只能建立單向連接的socket通信,也就是說只能將服務器作爲服務端來等待客戶端的連接。所以我們將服務器作爲服務端,在服務器上新建一個server.py文件(和局域網之間通信的服務端server.py沒什麼區別,只是綁定的IP爲服務器自己的IPserver.bind(('192.168.27.238', 6688))改爲server.bind(('220.181.111.188', 6688))220.181.111.188是百度的IP,改爲你的服務器IP),然後在本機建一個client.py文件,內容和局域網之間通信的client.py一致,只是連接的IP改爲服務器的IP(client.connect(('192.168.27.238', 6688))改爲client.connect(('220.181.111.188', 6688)),這裏就不冗餘的貼代碼了)。

結語

       到此局域網內和局域網與廣域網的持續通信初步實現已經差不多了,不過上述代碼也只能是一對一的通信,一對多不是本篇博客的內容,因爲客戶端一般都不會只有一個,所以這個一對一不能滿足我們的常用需求。在下一篇博客會介紹多線程實現多客戶端連接服務器,與服務器通信。

上一篇:Python Socket網絡編程(一)初識Socket和Socket初步使用
下一篇:Python Socket網絡編程(三)Socket多線程實現多客戶端與服務器通信

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章