python——初識socket


什么是socket  

  網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個端口上,不同的端口對應於不同的服務。

  Socket的英文原義是“孔”或“插座”。Socket正如其英文原意那樣,像一個多孔插座。一台主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟件將插頭插到不同編號的插座,就可以得到不同的服務。

  我知道上面那段話很枯燥,那就忘記吧!我們只需要記得:兩個程序通過“網絡”交互數據就使用socket,它只負責兩件事:建立連接,傳遞數據。不能再簡練了!!!

如何執行一段socket代碼?

  首先,我們先看下面這個例子,什么都不需要懂,我們只知道這么寫就可以實現一個socket,讓兩個程序互相傳遞消息:

  server:     client:                      

  先說一下它們是怎么跑起來的,新建兩個python文件:socket_server.py,socket_client.py 分別將demo1_server Codedemo1_client Code中的代碼粘到對應的文件中,先執行socket_server.py,再執行socket_client.py,就可以看到效果啦!代碼拿去,先體驗一下socket的效果。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 __author__ = 'Eva_J'
 4 import socket
 5 
 6 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 7 sock.bind(('127.0.0.1',8001))
 8 sock.listen(5)
 9 
10 while True:
11     print 'waiting....'
12     connection, address = sock.accept()
13     receive = connection.recv(1024)
14     print 'receive the message from client:',receive
15     connection.send("received")
16     connection.close()
demo1_server Code
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 __author__ = 'Eva_J'
 4 import socket
 5 
 6 obj_client = socket.socket()
 7 obj_client.connect(('127.0.0.1',8001))
 8 obj_client.send('help')
 9 server_data = obj_client.recv(1024)
10 print server_data
11 obj_client.close()
demo1_client Code

一分鍾擁有一個自己的socket程序!

  執行成功了么?我們先不解釋原理,一切以能把socket用起來為前提,把上面這段代碼當做實現socket的模板代碼,來看看哪些東西是我們可以替換的,先拼湊一個屬於自己的socket程序。

  server:        client:

                          

  我們先從打印出來的內容來看,server端接收到了從client端發送過來的信息 'help' 。並且給client端發送了一條確認信息 'received',我們在client端接收到了這條信息。這就是數據交互的過程。send是發消息方法,recv是接收消息方法。我們只需要修改send和recv中的內容,就可以實現兩個程序的數據交互了。

  socket的實現就像是快遞員取快遞的過程,寄出包裹的是server端,快遞員是client端,send和recv中的內容就是我們要寄出的東西,那么准備好了要寄出的東西,我們要告訴快遞員到哪里來取件,看server中的sock.bind方法,這里面傳了一個元組('ip','port')給bind方法,就是把包裹放在這個地址的這個端口等待快遞員;而client端的obj_client.connect方法是告訴快遞員,去那個地址找這個端口去取包裹。所以這個元組中的ip和port內容必須一致,是我和快遞員約好的。我send的內容無所謂是什么,我send什么,客戶端就recv什么,因為我要寄什么,快遞員拿到的就是什么,他沒有權利左右我寄什么東西。現在就行動起來,把要寄的東西和放東西的地址換成你自己的,來get一個屬於自己的socket程序吧。

socket程序代碼詳解:

   server:     client:

 創建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 ,則系統就會根據地址格式和套接類別,自動選擇一個合適的協議'

UDP協議實現socket代碼實例:

  我們剛剛看的例子中都是使用TCP協議進行傳輸,下面上一段UDP的例子。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import socket
 4 ip_port = ('127.0.0.1',9999)
 5 
 6 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
 7 while True:
 8     inp = raw_input('數據:').strip()
 9     if inp == 'exit':
10         break
11     sk.sendto(inp,ip_port)
12 sk.close()
UDP Server Code
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
sk.bind(ip_port)

while True:
    data = sk.recv(1024)
    print data
UDP Client Code

 

參考:

socket詳解:http://www.cnblogs.com/wupeiqi/articles/5040823.html

TCP和UDP協議的區別:http://jingyan.baidu.com/article/6dad5075df3452a123e36ecb.html


免責聲明!

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



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