【Socket】Python UDP和TCP的socket實例

Socket

Socket又稱」套接字」,應用程序一般經過」套接字」向網絡發出請求或者應答網絡請求。 具體定義看百科 python

socket有兩種,一種基於UDP,一種基於TCP。UDP是面向非鏈接的,傳遞的是數據報,每次傳遞都要指定目的地址端口;而TCP是面向鏈接的,通過三次握手協議創建起鏈接,因此不用每次都指定目的地址端口。固然還有不少的區別,這裏就不一一列舉。git

通常服務器端和客戶端各有一個socket,你能夠將它當作是一個網絡接口,將你的請求轉化成底層數據,把收到的數據轉化成高級的數據對象。github

在Python中用於socket編程的包是socket,這是一個自帶的包。web

UDP socket

UDP Server端

#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


UDP Client端

#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是徹底同樣的。


TCP socket

TCP 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


TCP Client端

#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。

總結:

  1. Server端都要用bind()綁定地址和端口。

  2. 區別TCP和UDP的是在創建ServerSocket對象時第二個參數不一樣,TCP是socket.socket(socket.AF_INET,socket.SOCK_DGRAM),而UDP是socket.socket(socket.AF_INET,socket.SOCK_STREAM)

  3. TCP的Server還須要有listen()方法監聽。

  4. TCP的Server端會經過accpet()方法獲得addrClientSocket,經過ClientSocketsend()recv()方法實現發送和接收。

  5. UDP的發送和接收方法是sendto()recvfrom,TCP的發送和接收方法是sendrecv,注意區分。

代碼下載:

博文中代碼點此下載

相關文章
相關標籤/搜索