python網絡編程基礎(一)


一、C/S架構

客戶端/服務端架構

二、OSI七層架構

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

分層:

應用層 (Application):

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

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

表示層(Presentation Layer):

數據的表示、安全、壓縮。(在五層模型里面已經合並到了應用層)

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

會話層(Session Layer):

建立、管理、終止會話。(在五層模型里面已經合並到了應用層)

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

傳輸層 (Transport):

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

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

網絡層 (Network):

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

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

數據鏈路層 (Link):

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

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

物理層(Physical Layer):

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

三、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狀態,完成四次揮手。

四、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()        創建一個與該套接字相關的文件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM