python網絡編程基礎(一)

1、C/S架構

客戶端/服務端架構python

2、OSI七層架構

七層模型,亦稱OSI(Open System Interconnection)參考模型,是參考模型是國際標準化組織(ISO)制定的一個用於計算機或通訊系統間互聯的標準體系。它是一個七層的、抽象的模型體,不只包括一系列抽象的術語或概念,也包括具體的協議。面試

分層:編程

應用層 (Application):

網絡服務與最終用戶的一個接口。緩存

協議有:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP安全

表示層(Presentation Layer):

數據的表示、安全、壓縮。(在五層模型裏面已經合併到了應用層)服務器

格式有,JPEG、ASCll、DECOIC、加密格式等網絡

會話層(Session Layer):

創建、管理、終止會話。(在五層模型裏面已經合併到了應用層)session

對應主機進程,指本地主機與遠程主機正在進行的會話架構

傳輸層 (Transport):

定義傳輸數據的協議端口號,以及流控和差錯校驗。app

協議有:TCP UDP,數據包一旦離開網卡即進入網絡傳輸層

網絡層 (Network):

進行邏輯地址尋址,實現不一樣網絡之間的路徑選擇。

協議有:ICMP IGMP IP(IPV4 IPV6) ARP RARP

創建邏輯鏈接、進行硬件地址尋址、差錯校驗等功能。(由底層網絡定義協議)

將比特組合成字節進而組合成幀,用MAC地址訪問介質,錯誤發現但不能糾正。

物理層(Physical Layer):

創建、維護、斷開物理鏈接。(由底層網絡定義協議)

3、TCP的三段握手和四次斷開

相對於SOCKET開發者,TCP建立過程和連接折除過程是由TCP/IP協議棧自動建立的.所以開發者並不須要控制這個過程.可是對於理解TCP底層運做機制,至關有幫助.

並且對於有網絡協議工程師之類筆試,幾乎是必考的內容.企業對這個問題熱情之高,出乎個人意料:-)。有時上午面試前強調這個問題,並重復講一次,下午幾乎每個人都被問到這個問題。

所以在這裏詳細解釋一下這兩個過程。

TCP三次握手

所謂三次握手(Three-way Handshake),是指創建一個TCP鏈接時,須要客戶端和服務器總共發送3個包。

三次握手的目的是鏈接服務器指定端口,創建TCP鏈接,並同步鏈接雙方的序列號和確認號並交換 TCP 窗口大小信息.在socket編程中,客戶端執行connect()時。將觸發三次握手。

第一次握手:
客戶端發送一個TCP的SYN標誌位置1的包指明客戶打算鏈接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段裏。

第二次握手:
服務器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均爲1同時,將確認序號(Acknowledgement Number)設置爲客戶的I S N加1以.即X+1。

第三次握手.
客戶端再次發送確認包(ACK) SYN標誌位爲0,ACK標誌位爲1.而且把服務器發來ACK的序號字段+1,放在肯定字段中發送給對方.而且在數據段放寫ISN的+1

TCP四次斷開

TCP的鏈接的拆除須要發送四個包,所以稱爲四次揮手(four-way handshake)。客戶端或服務器都可主動發起揮手動做,在socket編程中,任何一方執行close()操做便可產生揮手操做。

(1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
(2)第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
(3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
(4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。

4、socket

socket一般也稱做"套接字",用於描述IP地址和端口,是一個通訊鏈的句柄,應用程序一般經過"套接字"向網絡發出請求或者應答網絡請求。套接字能惟一表示出互聯網上一臺主機上的一個應用程序

socket起源於Unix,而Unix/Linux基本哲學之一就是「一切皆文件」,對於文件用【打開】【讀寫】【關閉】模式來操做。socket就是該模式的一個實現,socket便是一種特殊的文件,一些socket函數就是對其進行的操做(讀/寫IO、打開、關閉)

socket和file的區別:

file模塊是針對某個指定文件進行【打開】【讀寫】【關閉】
socket模塊是針對 服務器端 和 客戶端Socket 進行【打開】【讀寫】【關閉】

#server端
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8000)) #綁定手機卡
phone.listen(5)
print('---------')
while True:
    conn,addr=phone.accept()  #等電話

    print("電話線路是",conn)
    print("客戶端的手機號是",addr)
    while True:  #通信循環
        try:
            msg=conn.recv(1024)  #收消息
            if not msg:break
            print('客戶端發來的消息是:',msg)
            conn.send(msg.upper())#發消息
        except Exception:
            break
    conn.close()
phone.close()
#客戶端
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8000))
while True:
    msg=input(">>>:").strip()
    if not msg: continue
    phone.send(msg.encode('utf-8'))  #發送給服務端的消息
    data=phone.recv(1024)
    print('收到服務端發來的消息',data)
phone.close()

socket參數使用

## socket參數使用
參數一:地址簇

  socket.AF_INET IPv4(默認)
  socket.AF_INET6 IPv6

  socket.AF_UNIX 只可以用於單一的Unix系統進程間通訊

參數二:類型

  socket.SOCK_STREAM  流式socket , for TCP (默認)
  socket.SOCK_DGRAM   數據報式socket , for UDP

  socket.SOCK_RAW 原始套接字,普通的套接字沒法處理ICMP、IGMP等網絡報文,而SOCK_RAW能夠;其次,SOCK_RAW也能夠處理特殊的IPv4報文;此外,利用原始套接字,能夠經過IP_HDRINCL套接字選項由用戶構造IP頭。
  socket.SOCK_RDM 是一種可靠的UDP形式,即保證交付數據報但不保證順序。SOCK_RAM用來提供對原始協議的低級訪問,在須要執行某些特殊操做時使用,如發送ICMP報文。SOCK_RAM一般僅限於高級用戶或管理員運行的程序使用。
  socket.SOCK_SEQPACKET 可靠的連續數據包服務

參數三:協議

  0  (默認)與特定的地址家族相關的協議,若是是 0 ,則系統就會根據地址格式和套接類別,自動選擇一個合適的協議

其餘參數:sk是自定義的變量,s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

服務端套接字函數
s.bind()    綁定(主機,端口號)到套接字
s.listen()  開始TCP監聽
s.accept()  被動接受TCP客戶的鏈接,(阻塞式)等待鏈接的到來

客戶端套接字函數
s.connect()     主動初始化TCP服務器鏈接
s.connect_ex()  connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常

公共用途的套接字函數
s.recv()            接收TCP數據
s.send()            發送TCP數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)
s.sendall()         發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)
s.recvfrom()        接收UDP數據
s.sendto()          發送UDP數據
s.getpeername()     鏈接到當前套接字的遠端的地址
s.getsockname()     當前套接字的地址
s.getsockopt()      返回指定套接字的參數
s.setsockopt()      設置指定套接字的參數
s.close()           關閉套接字

面向鎖的套接字方法
s.setblocking()     設置套接字的阻塞與非阻塞模式
s.settimeout()      設置阻塞套接字操做的超時時間
s.gettimeout()      獲得阻塞套接字操做的超時時間

面向文件的套接字的函數
s.fileno()          套接字的文件描述符
s.makefile()        建立一個與該套接字相關的文件
相關文章
相關標籤/搜索