【Socket通訊】關於Socket通訊原理解析及python實現

來源:互聯網
上載者:User

Socket(通訊端)通訊{網路通訊其實就是Socket間的通訊},首先瞭解下概念:【來源於百度百科】

"兩個程式通過一個雙向的通訊串連實現資料的交換,這個串連的一端稱為一個socket。"

可以這麼說,Socket就是一個網路編程的介面(API),它定義了一種標準,並對TCP/IP進行封裝,實現了網路傳輸資料的能力。

這篇文章預設您已經瞭解IP、連接埠等基本網路概念,如未瞭解,請移步:baike.baidu.com/item/IP/224599

我們想象這麼一個情境,如果兩個人,想要互相送一份禮物【用某風快遞】,那麼每個人都需要知道對方的什麼資訊?

  1. 地址【IP】:不然你讓快遞公司送到哪裡?【不然你讓互連網供應商把資料送到哪台電腦?】
  2. 姓名【連接埠】:一個地點不一定住一個人啊,快遞小哥怎麼知道要送給誰?【一台電腦不一定只有一個程式使用網路啊,系統怎麼知道把資料傳給哪個程式?】

再一點,快遞公司有很多種,不一定非得選擇某風快遞,你也可以用某通快遞、某達快遞、某國郵政之類的,各有各的特點。在socket通訊中也是這樣,分為TCP、UDP兩種。

TCP(Transmission Control Protocol,傳輸控制通訊協定)是基於串連的協議,也就是說,在正式收發資料前,必須和對方建立可靠的串連。

UDP(User Data Protocol,使用者資料包通訊協定)是與TCP相對應的協議。它是面向非串連的協議,它不與對方建立串連,而是直接就把資料包發送過去!

關鍵詞我已經標記出來了,配合上面的情景引入,可以很容易的理解。既然各有各的特色,那麼根據生物學定理:“結構決定功能”,我們也很容易知道這倆東西肯定有不一樣的地方。

TCP,由於是基於雙方串連的情況下傳輸的,因此它的串連以及資料轉送是非常穩定可靠的,可以使一台電腦發出的位元組流完好無損的發生給另一台電腦。對要求可靠性非常高的應用程式會選擇此種通訊方式。

UDP,肯定是不太穩定的了,它適用於一次只傳送少量資料、對可靠性要求不高的應用環境。其實我們常常使用的【ping】命令的工作原理就是向對方主機發送ICMP資料包【自行百度】,然後對方主機確認收到資料包,如果資料包是否到達的訊息及時反饋回來,那麼網路就是通的。對了,QQ的聊天功能大部分是用UDP來實現的,因為這樣可以使得傳輸速率極快,但同時也會出現發生失敗的情況,更極端的就是遇到掉包的情況。

另外,關於Socket通訊還需理解的兩對概念:長串連與短串連非同步與同步【這個概念理解起來較難,但你可以先不理解,不會妨礙你實現小項目,在你實現完幾個小項目後,再反過來看這塊,你會有恍然大悟的感覺】

1、長串連 
       顧名思義,長串連就是連線時間更長的串連方式:串連——>傳輸資料——>等待——>傳輸資料…………——>結束
       Socket無論在是否使用都處於串連狀態,雖然佔用資源更小,但安全性較差。

2、短串連
        同樣也是顧名思義,短串連就是連線時間更短的串連方式,但會多次串連:串連——>傳輸資料——>結束  串連——>傳輸資料…………——>結束
       SOCKET串連後發送後接收完資料後馬上中斷連線。

 

1、非同步 
       報文發送和接收是分開的,相互獨立的,互不影響。這種方式又分兩種情況: 
       (1)非同步雙工:接收和發送在同一個程式中,由兩個不同的子進程分別負責發送和接收 
       (2)非同步單工:接收和發送是用兩個不同的程式來完成。 

2、同步 
       報文發送和接收是同步進行,既報文發送後等待接收返回報文。 同步方式一般需要考慮逾時問題,即報文發出去後不能無限等待,需要設定逾時時間,超過該時間發送方不再等待讀返回報文,直接通知逾時返回。
       在長串連中一般是沒有條件能夠判斷讀寫什麼時候結束,所以必須要加長度報文頭。讀函數先是讀取報文頭的長度,再根據這個長度去讀相應長度的報文。  

原諒我,同步非同步實在沒找到合適的圖,我也實在想不出怎麼來舉栗子能讓讀者更好的理解。我個人經曆是:做了個評測機【評測機和網站伺服器間用socket傳輸資料】後才理解的。

下面我們就得瞭解這些快遞公司到底如何?互動的?

先看這個圖,其實這個圖就可以概括一切了,但是為了讓大部分更好的理解,我再解釋下的。

首先,用戶端和服務端會分別建立一個socket,服務端的socket需要通過bind()來綁定上連接埠,啟動listen()進行即時監聽,並等待用戶端的接入,即accept()。而用戶端則需要通過伺服器IP和連接埠兩個參數來建立connect()串連,此時,伺服器會得到有新用戶端串連的資訊,啟動read()等待用戶端資料的傳人,用戶端如果成功接收到服務端的串連成功後,繼續執行write()來向服務端發生資料,同理,服務端也使用這樣的模式回饋用戶端的資料,知道用戶端關閉,服務端會收到用戶端退出串連的訊息,伺服器重新進入等待狀態,等待新用戶端的進入。

下面是用python寫的樣本,其他語言也都遵循上面的標準,C++採用的擴充庫來實現的,在<WINSOCKET2>這個庫中實現。

 1 import socket 2 #服務端 3 new_socket = socket.socket()         # 建立 socket 對象 4 ip = "127.0.0.1"          # 擷取本地主機名稱 5 port = 52052                # 設定連接埠 6 new_socket.bind((ip, port))        # 綁定連接埠 7 new_socket.listen(5)                 # 等待用戶端串連並設定最大串連數 8 while True: 9     new_cil, addr = new_socket.accept()     # 建立用戶端串連。10     print('新進來的用戶端的地址:', addr)11     print(new_cil.recv().decode())12     new_cil.send('答案為6')13     new_cil.close()                # 關閉串連
import socket#用戶端ip = "127.0.0.1"port = 52052new_socket = socket.socket()  #建立socket對象new_socket.connect((ip,port))  #串連new_socket.send("請求給我計算下1+5=多少?".encode(encoding='utf-8')) #發生資料print("用戶端發給服務端:請求給我計算下1+5=多少?") back_str = new_socket.recv().decode() #結束資料print("服務端發給用戶端:"+back_str)new_socket.close() #關閉用戶端print("用戶端結束運行")

 

人生苦短,我用python!隔壁C語言實現這個至少200行代碼!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.