Socket又稱」套接字」,應用程序一般經過」套接字」向網絡發出請求或者應答網絡請求。 具體定義看百科 python
socket有兩種,一種基於UDP,一種基於TCP。UDP是面向非鏈接的,傳遞的是數據報,每次傳遞都要指定目的地址端口;而TCP是面向鏈接的,通過三次握手協議創建起鏈接,因此不用每次都指定目的地址端口。固然還有不少的區別,這裏就不一一列舉。git
通常服務器端和客戶端各有一個socket,你能夠將它當作是一個網絡接口,將你的請求轉化成底層數據,把收到的數據轉化成高級的數據對象。github
在Python中用於socket編程的包是socket
,這是一個自帶的包。web
#coding=utf-8
import socket
import time
HOST = 'localhost' #主機,由於是本機因此是localhost,或者127.0.0.1也能夠
BUFFSIZE = 1024 #每次讀取數據的緩存區大小
PORT = 8802 #端口,也就是客戶端要鏈接的端口
ADDR = (HOST,PORT) #將主機地址和端口組成一個tuple形式的地址
UDPSerSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
UDPSerSocket.bind(ADDR)
print('waiting for connect...')
while True:
data,addr = UDPSerSocket.recvfrom(BUFFSIZE)
print 'Received',data,'from',addr,'in [%s]'%time.ctime()
UDPSerSocket.sendto('[%s]:%s'%(time.ctime(),data),addr)
UDPSerSocket.close()
說明:編程
UDPSerSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
中兩個參數,第一個是指定以internet地址鏈接,第一個參數還有一個值是AF_UNIX
,可是通常都不會用到,至少我還沒用到過。第二個參數是指定以何種方式傳輸,socket.SOCK_DGRAM
是以數據報的形式傳輸,也就是對應UDP方式,TCP方式是socket.socket.SOCK_STREAM
。緩存
UDPSerSocket.bind(ADDR)
是綁定地址,服務器端的socket必須執行這一步,計算機才知道這個socket對應那個端口,並能夠在這個端口監聽。服務器
服務器端的socket通常都會有一個while True
的循環,用於接收完數據以後立刻等待下一個數據。網絡
UDPSerSocket.recvfrom(BUFFSIZE)
是接收數據的方法,接受到的是一個data
數據和發送數據的地址addr
。以前咱們說過UDP方式是每一次都必須指定地址,因此這裏獲取到一個地址能夠在下一步的發送方法UDPSerSocket.sendto('[%s]:%s'%(time.ctime(),data),addr)
中用到。socket
最後,用完socket以後記得記性close()
方法釋放tcp
#coding=utf-8
import socket
HOST = 'localhost'
PORT = 8802
ADDR = (HOST,PORT)
BUFFSIZE = 1024
UDPcliSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
data = raw_input('>')
if not data:
break;
UDPcliSocket.sendto(data,ADDR)
datarecv,addr = UDPcliSocket.recvfrom(BUFFSIZE)
if not datarecv:
break
print datarecv
UDPcliSocket.close()
說明:
Client和Server創建socket對象的方法都是同樣的,不一樣的是Client端不須要綁定bind()
,由於Client是通常狀況下是主動鏈接的一方,而不是等待的一方。
Client端的接收和發送方法和Server是徹底同樣的。
#coding=utf-8
import socket
import time
HOST = 'localhost'
PORT = 8081
BUFFSIZE = 1024
ADDR = (HOST,PORT)
TCPSerSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
TCPSerSocket.bind(ADDR)
TCPSerSocket.listen(5)
while True:
print "waiting for connection..."
tcpCliSocket,addr = TCPSerSocket.accept()
print '...connected from:',addr
while True:
data = tcpCliSocket.recv(BUFFSIZE)
if not data:
break
tcpCliSocket.send('[%s] %s'%(time.ctime(),data))
print [time.ctime()],":",data
tcpCliSocket.close()
TCPSerSocket.close()
說明:
TCP與UDP的Server端創建socket對象差很少,不一樣的是在socket.socket(socket.AF_INET,socket.SOCK_STREAM)
第二個參數指定爲socket.SOCK_STREAM
,一樣也須要綁定地址端口。,還有TCP的ServerSocket還須要一個listen(5)
方法,表示監聽,不加會報錯。
咱們說TCP是面向鏈接的,因此在Client端鏈接到Server後並不會馬上斷開,而爲了能雙方通訊,Server會經過tcpCliSocket,addr = TCPSerSocket.accept()
收到一個ClientSocket對象,經過操做ClientSocket對象來完成接收、發送操做。
TCP接收方法是recv
與UDP的recvfrom
不一樣,其實想一想仍是挺容易理解的,UDP的recvfrom
方法除了獲得data
以外,還能獲得addr
,因此纔有from,而TCP早就已經獲得ClientSocket對象,固然也經過accept()
獲得了addr
,因此就沒有from咯。TCP的send
和UDP的sendto
也可如此理解。
固然仍是不要忘記執行close()
方法,也不要忘了關閉ClientSocket
。
#coding = utf-8
import socket
import time
HOST = 'localhost'
PORT = 8081
BUFFSIZE = 1024
ADDR = (HOST,PORT)
TCPCliSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
TCPCliSocket.connect(ADDR)
while True:
data = raw_input('>')
if not data:
break
TCPCliSocket.send(data)
data = TCPCliSocket.recv(BUFFSIZE)
if not data:
break
print '%s'%data
說明:
TCP與UDP的ClientSocket不一樣之處在於TCPClientSocket
要先創建鏈接,因此要執行connect()
方法,爲何?由於TCP是面向鏈接的。
Client端的發送和接收方法與TCP的Server相同,send()
和recv()
Client端不會像Server端那樣接收到對方的Socket的,爲何,由於不須要!通常Client是主動鏈接Server,就是用connect()
,那麼鏈接後Client就把本身的ClientSocket傳給Server,Server經過它來操做發送接收,而Client也就用ClientSocket接收和發送咯,你能夠將ClientSocket當作一個管道,經過這個管道來溝通Server和Client。
Server端都要用bind()
綁定地址和端口。
區別TCP和UDP的是在創建ServerSocket對象時第二個參數不一樣,TCP是socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
,而UDP是socket.socket(socket.AF_INET,socket.SOCK_STREAM)
。
TCP的Server還須要有listen()
方法監聽。
TCP的Server端會經過accpet()
方法獲得addr
和ClientSocket
,經過ClientSocket
的send()
和recv()
方法實現發送和接收。
UDP的發送和接收方法是sendto()
和recvfrom
,TCP的發送和接收方法是send
和recv
,注意區分。
博文中代碼點此下載