Part 8.網絡編程--Socket, Udp

(一)socket簡介python

1.本地的進程間通訊(IPC)有不少種方式,例如

  • 隊列
  • 同步(互斥鎖、條件變量等)

以上通訊方式都是在一臺機器上不一樣進程之間的通訊方式,那麼問題來了編程

網絡中進程之間如何通訊?也就是要從一臺電腦的某個進程把數據經過網絡傳到另外一臺電腦上的某個進程如何實現呢?服務器

2. 網絡中進程之間如何通訊

首要解決的問題是如何惟一標識一個進程,不然通訊無從談起!網絡

本地能夠經過進程PID來惟一標識一個進程,可是在網絡中這是行不通的。socket

其實TCP/IP協議族已經幫咱們解決了這個問題,網絡層的「ip地址」能夠惟一標識網絡中的主機,而傳輸層的「協議+端口」能夠惟一標識主機中的應用程序(進程)。tcp

這樣利用ip地址,協議,端口就能夠標識網絡的進程了,網絡中的進程通訊就能夠利用這個標誌與其它進程進行交互。函數

3. 什麼是socket

socket(簡稱 套接字) 是進程間通訊的一種方式,它與其餘進程間通訊的一個主要不一樣是:編碼

它能實現不一樣主機間的進程間通訊,咱們網絡上各類各樣的服務大多都是基於 Socket 來完成通訊的spa

例如咱們天天瀏覽網頁、QQ 聊天、收發 email 等等操作系統

4. 建立socket

在 Python 中 使用socket 模塊的函數 socket 就能夠完成:

socket.socket(AddressFamily, Type)

說明:

函數 socket.socket 建立一個 socket,返回該 socket 的描述符,該函數帶有兩個參數:

  • Address Family:能夠選擇 AF_INET(用於 Internet 進程間通訊) 或者 AF_UNIX(用於同一臺機器進程間通訊),實際工做中經常使用AF_INET
  • Type:套接字類型,能夠是 SOCK_STREAM(流式套接字,主要用於 TCP 協議)或者 SOCK_DGRAM(數據報套接字,主要用於 UDP 協議

建立實例:

1 import socket
2 
3 #建立tcp套接字
4 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5 #建立udp套接字
6 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

 

(二)UDP介紹

  • 簡介

UDP --- 用戶數據報協議,是一個無鏈接的簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,可是並不能保證它們能到達目的地。因爲UDP在傳輸數據報前不用在客戶和服務器之間創建一個鏈接,且沒有超時重發等機制,故而傳輸速度很快

UDP是一種面向無鏈接的協議,每一個數據報都是一個獨立的信息,包括完整的源地址或目的地址,它在網絡上以任何可能的路徑傳往目的地,所以可否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。

  • 特色

UDP是面向無鏈接的通信協議,UDP數據包括目的端口號和源端口號信息,因爲通信不須要鏈接,因此能夠實現廣播發送。 UDP傳輸數據時有大小限制,每一個被傳輸的數據報必須限定在64KB以內。 UDP是一個不可靠的協議,發送方所發送的數據報並不必定以相同的次序到達接收方。

  • 適用狀況

UDP是面向消息的協議,通訊時不須要創建鏈接,數據的傳輸天然是不可靠的,UDP通常用於多點通訊和實時的數據業務,好比:語音廣播,視頻,QQ,TFTP(簡單文件傳送),SNMP(簡單網絡管理協議),RIP(路由信息協議,如報告股票市場,航空信息),DNS(域名解釋)

注重速度流暢

UDP操做簡單,並且僅須要較少的監護,所以一般用於局域網高可靠性的分散系統中client/server應用程序。例如視頻會議系統,並不要求音頻視頻數據絕對的正確,只要保證連貫性就能夠了,這種狀況下顯然使用UDP會更合理一些。

 

(三)udp網絡程序---發送,接受數據

建立一個udp客戶端程序的流程是簡單,具體步驟以下:

  1. 建立客戶端套接字
  2. 發送/接收數據
  3. 關閉套接字

實例代碼:

 1 from socket import *
 2 
 3 #1.建立udp套接字
 4 udpSocket = socket(AF_INET, SOCK_DGRAM)
 5 
 6 #2.準備接收方地址
 7 sendAddr = ('192.168.254.1', 8080)
 8 
 9 #3.從鍵盤上獲取輸入內容
10 sendData = input("請輸入數據:")
11 
12 #4.發送數據到指定的電腦上
13 udpSocket.sendto(sendData.encode('gb2312'), sendAddr)
14 
15 #5等待接受對方發送的數據
16 recvData = udpSocket.recvfrom(1024)
17 
18 #6.顯示對方發送的數據
19 recvContent,recvAddr = recvData
20 print(recvContent.decode('gb2312'), recvAddr)
21 
22 #7.關閉套接字
23 udpSocket.close()

網絡調試助手截圖:

這裏須要注意13行代碼,咱們傳輸要進行編碼後才能傳輸,可採用國際通用的‘UTF-8’或者我國的‘gb2312’,當咱們傳輸過去後,對方須要進行解碼,當對方傳過來時,咱們須要解碼,因此,咱們須要瞭解對方的編碼方式,不然有時會出現亂碼的狀況。

 

(四)udp網絡程序--端口問題

  •  會變的端口號:

 從新運行屢次程序,而後在「網絡調試助手」中,看到的現象以下:

說明:

  • 每從新運行一次網絡程序,上圖中紅圈中的數字不同的緣由在於,這個數字標識這個網絡程序,當從新運行時,若是沒有肯定到底用哪一個,系統默認會隨機分配;
  • 記住一點:這個網絡程序在運行的過程當中,這個就惟一標識這個程序,因此若是其餘電腦上的網絡程序若是想要向此程序發送數據,那麼就須要向這個數字(即端口)標識的程序發送便可。

 

(五)udp綁定信息

  • 綁定信息

以前咱們說一個網絡程序在每次運行的時候端口是隨機變化的

通常狀況下,在一天電腦上運行的網絡程序有不少,而各自用的端口號不少狀況下不知道,爲了避免與其餘的網絡程序佔用同一個端口號,每每在編程中,udp的端口號通常不綁定。

可是若是須要作成一個服務器端的程序的話,是須要綁定的,想一想看這又是爲何呢?

  • 綁定實例  
 1 #coding=utf-8
 2 
 3 from socket import *
 4 
 5 #1. 建立套接字
 6 udpSocket = socket(AF_INET, SOCK_DGRAM)
 7 
 8 #2. 綁定本地的相關信息,若是一個網絡程序不綁定,則系統會隨機分配
 9 bindAddr = ('', 7788) # ip地址和端口號,ip通常不用寫,表示本機的任何一個ip
10 udpSocket.bind(bindAddr)
11 
12 #3. 等待接收對方發送的數據
13 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字節數
14 
15 #4. 顯示接收到的數據
16 print recvData
17 
18 #5. 關閉套接字
19 udpSocket.close()
  • 總結

一個udp網絡程序,能夠不綁定,此時操做系統會隨機進行分配一個端口,若是從新運行次程序端口可能會發生變化

一個udp網絡程序,也能夠綁定信息(ip地址,端口號),若是綁定成功,那麼操做系統用這個端口號來進行區別收到的網絡數據是不是此進程的

 

(六)udp網絡通訊過程

 

如上就是其一個簡單的演示,當咱們從傳輸方傳輸數據時,每通過一層便會給它加上一些信息也叫作組包,而後傳給接收方,接收方接受後每通過一層又會相應的解包,最後把信息傳給指定進程。

相關文章
相關標籤/搜索