1. 程式人生 > >day25 網路程式設計之socket

day25 網路程式設計之socket

1.  為什麼要學習socket?

    socket就是網路通訊的工具,任何一門語言都有socket,他不是任何一個語言的專有名詞,而是大家通過自己的程式與其他電腦進行網路通訊的時候都用它。

2.  客戶端,服務架構

    客戶端英文名稱:Client(使用服務端的服務),服務端英文名稱:Server(一直執行著,等待服務別人,不能有一天訪問百度,百度頁面打不開,不行吧。),下面所說的C\S架構就是說的Client\Server架構。

    a.硬體C\S架構:印表機。

    b.軟體C\S架構:

      B\S架構:瀏覽器(browser)\服務端>>>統一介面

3.  網路通訊的整個流程

    電腦插網線的地方就做網絡卡,網絡卡提供了網路的介面,這是硬體上面的,大家都是到網口是吧,我怎麼找到電腦的網絡卡呢,有人說用IP地址,IP地址並不是,而是全球唯一的mac地址,專門給網路裝置設定的,是出廠的時候就給定好的,一個裝置的mac地址號碼是全球唯一的。 head中包含的源和目標地址由來:ethernet規定接入internet的裝置都必須具備網絡卡,傳送端和接收端的地址便是指網絡卡的地址,即mac地址。   mac地址:每塊網絡卡出廠時都被燒製上一個世界唯一的mac地址,長度為48位2進位制,通常由12位16進位制數表示(前六位是廠商編號,後六位是流水線號)

      檢視mac地址的方法:windows下在cmd視窗輸入ipconfig -all指令:下面顯示的這個實體地址就是mac地址。

 

例. 瀏覽器訪問京東網站

流程描述:

第一步:開啟瀏覽器,想要請求訪問京東,在位址列輸入了網址:www.jd.com。(www.jd.com是域名就是一個IP地址的名稱,IP地址不好記,所有有了域名。)

第二步:先將請求資訊發給了交換機,然後交給了路由器,路由發給DNS伺服器,通過DNS協議去找我們要訪問的京東的IP地址:

第三步:查到的京東伺服器對應的IP地址之後,路由器通過路由協議找到一個路由轉發的最優路徑,將你的請求資訊還送給這個IP地址的京東的路由器

第四步:京東的路由器發給了京東網站的伺服器上

第五步:京東網站伺服器按照來的時候的路徑,在返回給你他自己的網站

第六步:當你開啟瀏覽器的時候,你的電腦給你的瀏覽器這個執行起來的程式給了一個編號,叫做埠號,當你的電腦收到京東傳送過來的訊息的時候,你的電腦通過埠號找到你的瀏覽器,你的瀏覽器拿到了京東的網站資訊,然後將網站呈現在了自己的瀏覽器上

 

內網和外網:  

    真正區域網與廣域網的分別是通過IP地址來實現的。
    任何一臺電腦要上網,都必須在網路上有一個唯一的IP地址。在區域網內,這個IP地址是唯一的。但是在另外一個區域網,這個IP地址仍然能夠使用。
    網路A裡有一臺IP地址為192.168.1.231的客戶端,網路B裡也可以有一臺同樣IP的電腦。那麼。我們就說這2臺機器分別在2個局域網裡。但是在廣域網內,所有的IP地址都是唯一的。山西電信的DNS伺服器IP地址是61.134.1.4.那麼,這個地址在全世界都是唯一的,不可重複的。這就是廣域網和區域網的區別。

    如果只有內網的ip地址你是不能上網的,你上網肯定要通過一個外網地址,這個外網地址又稱為公網地址,這個公網地址是全球唯一的,他在你的對外出口的路由器上,也就是你的外網閘道器地址。

DNS伺服器

    當我們請求https:\\www.JD.com的時候,首先電腦會在本地的DNS快取中找是否有這個DNS快取(DNS(Domain Name Server,域名伺服器)是進行域名(domain name)和與之相對應的IP地址 (IP address)轉換的伺服器。DNS中儲存了一張域名(domain name)和與之相對應的IP地址 (IP address)的表,以解析訊息的域名。 域名是Internet上某一臺計算機或計算機組的名稱,用於在資料傳輸時標識計算機的電子方位(有時也指地理位置)。域名是由一串用點分隔的名字組成的,通常包含組織名,而且始終包括兩到三個字母的字尾,以指明組織的型別或該域所在的國家或地區。 DNS是計算機域名系統 (Domain Name System 或Domain Name Service) 的縮寫,它是由域名解析器和域名伺服器組成的。域名伺服器是指儲存有該網路中所有主機的域名和對應IP地址,並具有將域名轉換為IP地址功能的伺服器。其中域名必須對應一個IP地址,一個IP地址可以有多個域名,而IP地址不一定有域名。域名系統採用類似目錄樹的等級結構。域名伺服器通常為客戶機/伺服器模式中的伺服器方,它主要有兩種形式:主伺服器和轉發伺服器。將域名對映為IP地址的過程就稱為“域名解析”。)本地的DNS快取是在我們訪問過一個網站之後,例如京東,那麼本地會儲存一個京東域名和京東伺服器IP地址的對映關係,將來再次請求的時候,就不用再到外部的DNS上查詢這個域名對應的IP地址了,提高了效率,如果是第一次請求,請看上面的DNS查詢過程

 

閘道器:   

    我們經常說的閘道器是指的傳輸閘道器,簡稱閘道器,我們主要就看它,閘道器在路由器這裡,當請求資訊傳送到了閘道器這裡的時候,我們先到路由表裡面看看有沒有這個請求的目標地址的IP,如果沒有說明不是我們自己網路內部的IP地址,需要路由轉發出去,到internet網路中,但是網路這麼大,怎麼辦,那麼通過閘道器計算出一個最佳的傳輸路徑去找到對應的目標閘道器地址,在路由轉發的過程中(當請求被路由B接收到了之後,路由B開啟之後發現不是找自己的,就會把請求資訊包繼續轉發)然後傳輸到這個閘道器地址的路由器上,目標閘道器路由器上設定了一些IP地址+埠和各個伺服器上的對映關係,即便是所有的交換機都接收到了這個請求,但是還是能夠找到對應的伺服器。在通過交換機發送到對應的伺服器上

    那麼閘道器到底是什麼呢?閘道器實質上是一個網路通向其他網路的IP地址。比如有網路A和網路B,網路A的IP地址範圍為 “192.168.1.1~192. 168.1.254”,子網掩碼為255.255.255.0;網路B的IP地址範圍為“192.168.2.1~192.168.2.254”,子網掩碼為255.255.255.0。在沒有路由器的情況下,兩個網路之間是不能進行TCP/IP通訊的,即使是兩個網路連線在同一臺交換機(或集線器)上, TCP/IP協議也會根據子網掩碼(255.255.255.0)判定兩個網路中的主機處在不同的網路裡。而要實現這兩個網路之間的通訊,則必須通過閘道器。如果網路A中的主機發現資料包的目的主機不在本地網路中,就把資料包轉發給它自己的閘道器,再由閘道器轉發給網路B的閘道器,網路B的閘道器再轉發給網路B的某個主機。網路B向網路A轉發資料包的過程也是如此。

       埠+IP能夠確定一臺電腦上的某一個應用程式~~

    

3.    socket

import socket
#建立一個socket物件
server = socket.socket()  #相當於建立了一部電話
ip_port = ('192.168.111.1',8001) #建立一個電話卡
server.bind(ip_port) #插上電話卡
server.listen(5) #監聽著電話,我能監聽5個,接到一個電話之後,後面還能有四個人給我打電話,但是後面這四個人都要排隊等著,等著我第一個電話掛掉,再來第6個的時候,第六個人的手機會報錯
print('11111')
#等著別人給我打電話,打來電話的時候,我就拿到了和對方的這個連線通道conn和對方的電話號碼addr
conn,addr = server.accept()  #阻塞住,一直等到有人連線我,連線之後得到一個元祖,裡面是連線通道conn和對方的地址(ip+埠)
print('22222')
print(conn)
print('>>>>>>>>>',addr)
while True:
    from_client_data = conn.recv(1024) #服務端必須通過兩者之間的連線通道來收訊息
    from_client_data = from_client_data.decode('utf-8')
    print(from_client_data)
    if from_client_data == 'bye':
        break
    server_input = input('明威說>>>>:')
    conn.send(server_input.encode('utf-8'))
    if server_input == 'bye':
        break
conn.close() #掛電話
server.close() #關手機

test_server.py
#_*_coding:utf-8_*_
import socket
import time

client = socket.socket()
server_ip_port = ('192.168.111.1',8001)

client.connect(server_ip_port)

while True:
    client_input = input('小文說>>>>:')
    client.send(client_input.encode('utf-8')) #給服務端傳送訊息
    if client_input == 'bye':
        break
    from_server_data = client.recv(1024)

    print('來自服務端的訊息:',from_server_data.decode('utf-8'))
    if from_server_data.decode('utf-8') == 'bye':
        break
client.close() #客戶端掛電話

test_client.py

注意:先執行server,然後再執行client,然後你會發現client這個檔案再輸出臺的地方讓你輸入內容,你輸入一個內容然後回車,你會發現server那邊的控制檯就輸出了以client傳送的內容