網絡編程之Socket

網絡編程之Socket

咱們已經知道,假設我如今要寫一個程序,給另外一臺計算機發數據,必須經過tcp/ip協議 ,但具體的實現過程是什麼呢?我應該怎麼操做才能把數據封裝成tcp/ip的包,又執行什麼指令才能把數據發到對端機器上呢? 不能只有世界觀,沒有方法論呀。。。此時,socket隆重登場,簡而言之,socket這個東東干的事情,就是幫你把tcp/ip協議層的各類數據封裝啦、數據發送、接收等經過代碼已經給你封裝好了,你只須要調用幾行代碼,就能夠給別的機器發消息了。python

1、Socket介紹

一、什麼是Socket編程

Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層。它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有。設計模式

socket起源於Unix,而Unix/Linux基本哲學之一就是「一切皆文件」,均可以用「打開open –> 讀寫write/read –> 關閉close」模式 來操做。Socket就是該模式的一個實現,socket便是一種特殊的文件,一些socket函數就是對其進行的操做(讀/寫IO、打開、關閉)。瀏覽器

你想給另外一臺計算機發消息,你知道他的IP地址,他的機器上同時運行着qq、迅雷、word、瀏覽器等程序,你想給他的qq發消息,那想一下,你如今只能經過ip找到他的機器,但若是讓這臺機器知道把消息發給qq程序呢?答案就是經過port,一個機器上能夠有0-65535個端口,你的程序想從網絡上收發數據,就必須綁定一個端口,這樣,遠程發到這個端口上的數據,就全會轉給這個程序。緩存

二、Socket通訊套路安全

當經過socket創建起2臺機器的鏈接後,本質上socket只幹2件事,一是收數據,一是發數據,沒數據時就等着。服務器

socket 創建鏈接的過程跟咱們現實中打電話比較像,打電話必須是打電話方和接電話方共同完成的事情,咱們分別看看他們是怎麼創建起通話的。網絡

接電話方:app

1.首先你得有個電話

2.你的電話要有號碼

3.你的電話必須連上電話線

4.開始在家等電話

5.電話鈴響了,接起電話,聽到對方的聲音

打電話方:socket

1.首先你得有個電話

2.輸入你想撥打的電話

3.等待對方接聽

4.say 「hi 約麼,我有七天酒店的打折卡噢~」

5.等待迴應——》響應迴應——》等待迴應。。。。

把上述事件翻譯成socket通訊

接電話方(socket服務器端):

1.首先你得有個電話\(生成socket對象\)

2.你的電話要有號碼\(綁定本機ip+port\)

3.你的電話必須連上電話線\(連網\)

4.開始在家等電話\(開始監聽電話listen\)

5.電話鈴響了,接起電話,聽到對方的聲音\(接受新鏈接\)

打電話方(socket客戶端):

1.首先你得有個電話\(生成socket對象\)

2.輸入你想撥打的電話\(connect 遠程主機ip+port\)

3.等待對方接聽

4.say 「hi 約麼,我有七天酒店的打折卡噢~」\(send\(\) 發消息。。。\)

5.等待迴應——》響應迴應——》等待迴應。。。。

2、Socket套接字方法

一、socket實例類

socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

family(socket家族)

  • socket.AF_UNIX:用於本機進程間通信,爲了保證程序安全,兩個獨立的程序(進程)間是不能互相訪問彼此的內存的,但爲了實現進程間的通信,能夠經過建立一個本地的socket來完成。
  • socket.AF_INET:(還有AF_INET6被用於ipv6,還有一些其餘的地址家族,不過,他們要麼是隻用於某個平臺,要麼就是已經被廢棄,或者是不多被使用,或者是根本沒有實現,全部地址家族中,AF_INET是使用最普遍的一個,python支持不少種地址家族,可是因爲咱們只關心網絡編程,因此大部分時候我麼只使用AF_INET)。

socket type 類型

  • socket.SOCK_STREAM # for TCP
  • scoket.SOCK_DGRAM # 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 # 廢棄了。

Only SOCK_STREAM and SOCK_DGRAM appear to be generally useful.

proto=0

可忽略,特殊用途才考慮。

fileno=None

可忽略,特殊用途才考慮。

二、服務端套接字函數

設s爲socket實例化的一個對象

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

三、客戶端套接字函數

設s爲socket實例化的一個對象

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

四、公共用途的套接字函數

設s爲socket實例化的一個對象

  • s.recv() 接收數據。
  • s.send() 發送數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)
  • s.sendall() 發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)。
  • s.recvform() Receive data from the socket. The return value is a pair (bytes, address)
  • s.getpeername() 鏈接到當前套接字的遠端的地址。
  • s.close() 關閉套接字。
  • socket.setblocking(flag) # True or False,設置socket爲非阻塞模式。
  • socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) 返回遠程主機的地址信息,例如:socket.getaddrinfo('luffycity.com', 80)
  • socket.getqdn() 拿到本機的主機名。
  • socket.gethostbyname() 經過域名解析ip地址。
相關文章
相關標籤/搜索