更多課程 選擇中心

Python培訓
美國上市教育機構

400-111-8989

Python培訓

Python 網絡編程基礎入門

  • 發布:Python培訓
  • 來源:知識
  • 時間:2018-01-23 15:45

作者:再見紫羅蘭

來源:http://www.cnblogs.com/linxiyue/p/8265006.html

Python的網絡編程主要支持兩種網絡協議:TCP和UDP。這兩種協議都通過叫Socket的編程抽象進行處理。Socket起源于Unix,是類似于文件的存在,可以像文件一樣進行I/O、打開、關閉等操作,最主要的是它可以實現網絡上不同主機的進程間通信,所以基本上Socket是任何一種網絡通訊中最基礎的內容。

Python中建立一個套接字很簡單:

  1. import socket

  2. s = socket.socket(family, type)

地址族

family為地址族,該族指定要使用的網絡協議,主要使用的有:

  • AF_INET:IPv4協議(TCP,UDP)

  • AF_INET6:IPv6協議(TCP,UDP)

  • AF_UNIX:UNIX域協議,用于同一臺機器的進程間通訊

套接字類型

type為套接字類型,指定給定的協議組中使用的通信類型:

  • SOCK_STREAM:用于TCP

  • SOCK_DGRAM:用于UDP

TCP和UDP都是基于Client/Server的編程模型,所以Socket編程也分為客戶端和服務器端,以TCP為例:

TCP客戶端編程

要獲取遠程主機的ip地址,可以使用socket標準庫提供的gethostbyname()方法:

  1. >>> import socket

  2. >>> socket.gethostbyname('www.baidu.com')

  3. '115.239.211.112'

socket套接字實例s可用于客戶端的方法有以下幾個:

  • s.connect(addr):連接服務器端套接字。addr格式取決于地址族,對于IPv4來說,是一個包含ip地址與端口的元組,(host, port)。連接失敗會報socket.error錯誤。

  • s.sendall(string):嘗試發送所有數據,成功則返回None,失敗則報異常。

  • s.recv(bufsize):接收數據,bufsize指定接收的最大數據量。

  • s.close():關閉套接字

OK,現在可以用socket向遠程主機發送一個HTTP GET請求了:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #建立套接字

  4. host = 'www.baidu.com'

  5. port = 80

  6. ip = socket.gethostbyname(host)  #獲取ip

  7. s.connect((ip, port))  #建立連接

  8. message = 'GET / HTTP/1.1rnrn'

  9. s.sendall(message)  #發送GET請求

  10. r = s.recv(4096)    #接收數據

  11. print r

  12. s.close()    #關閉套接字

返回:

  1. HTTP/1.1 302 Moved Temporarily

  2. Date: Wed, 10 Jan 2018 18:56:45 GMT

  3. Content-Type: text/html

  4. Content-Length: 225

  5. Connection: Keep-Alive

  6. Location: http://www.baidu.com/search/error.html

  7. Server: BWS/1.1

  8. X-UA-Compatible: IE=Edge,chrome=1

  9. BDPAGETYPE: 3

  10. Set-Cookie: BDSVRTM=0; path=/

下面我們可以實現自己的服務器。

TCP服務器端編程

Socket實例與服務器端編程有關的方法有以下幾個:

  • s.bind(addr):addr也是(host, port)形式的元組,將套接字綁定到特定的地址和端口上??兆址硎救我獾刂?,'broadcast'可以用做發送廣播信息。

  • s.listen(backlog):開始監聽連接,backlog為最大掛起連接次數。

  • s.accept:返回元組(conn,addr),conn為新的套接字,可以用來發送和接收數據。addr是客戶端的套接字地址。

  • s.recv()、s.sendall()和s.close()與客戶端同。

現在寫一個將客戶端發送來的信息發送回去的服務器:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. import sys

  4. HOST = ''  

  5. PORT = 8088

  6. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  7. s.bind((HOST, PORT))

  8. s.listen(5)

  9. print '開始監聽'

  10. conn, addr = s.accept()

  11. print 'Connected with ' + addr[0] + ':' + str(addr[1])

  12. data = conn.recv(1024)

  13. conn.sendall(data)

  14. conn.close()

  15. s.close()

運行:

服務器開始監聽連接了。修改一下剛才寫的客戶端程序:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  4. host = 'localhost'

  5. port = 8088

  6. s.connect((host, port))  #建立連接

  7. message = 'GET / HTTP/1.1rnrn'

  8. s.sendall(message)  #發送GET請求

  9. r = s.recv(4096)    #接收數據

  10. print r

  11. s.close()    #關閉套接字

運行,連接本地的服務器,服務器端輸出:

  1. >>>

  2. 開始監聽

  3. Connected with 127.0.0.1:60933

連接成功??蛻舳溯敵觯?

發送的消息被返回了。

這就是一個最簡單的服務器了。上述服務器只能處理一次連接,這顯然不是我們想看到的,保持一直運行:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. import sys

  4. HOST = ''  

  5. PORT = 8088

  6. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  7. s.bind((HOST, PORT))

  8. s.listen(5)

  9. print '開始監聽'

  10. while True:

  11.    conn, addr = s.accept()

  12.    print 'Connected with ' + addr[0] + ':' + str(addr[1])

  13.    data = conn.recv(1024)

  14.    conn.sendall(data)

  15.    conn.close()

  16. s.close()

現在就可以使用客戶端無限連接了:

  1. >>>

  2. 開始監聽

  3. Connected with 127.0.0.1:61240

  4. Connected with 127.0.0.1:61242

  5. Connected with 127.0.0.1:61245

  6. Connected with 127.0.0.1:61250

服務器端多線程處理連接

現在服務器端雖然可以處理無限多個連接,但只能一個一個的處理,后面的客戶端連接只能等待前面的連接完成才能發送數據。要同時處理多個連接,可以使用多線程。服務器端接收到新的連接后,開啟一個線程處理新連接,主線程去建立下一個連接。

服務器端:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. import threading

  4. HOST = ''  

  5. PORT = 8088

  6. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  7. s.bind((HOST, PORT))

  8. s.listen(5)

  9. print '開始監聽'

  10. def runThread(conn):

  11.    data = conn.recv(1024)

  12.    print data

  13.    conn.sendall(data)

  14.    conn.close()

  15. while True:

  16.    conn, addr = s.accept()

  17.    print 'Connected with ' + addr[0] + ':' + str(addr[1])

  18.    t = threading.Thread(target=runThread, args=(conn,))

  19.    t.daemon = True

  20.    t.start()

客戶端啟動多個連接:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. import time

  4. import threading

  5. def run():

  6.    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  7.    host = 'localhost'

  8.    port = 8088

  9.    s.connect((host, port))

  10.    message = 'GET / HTTP/1.1rnrn'

  11.    s.sendall(message)

  12.    print s.recv(4096)    

  13.    s.close()

  14. if __name__ == '__main__':

  15.    for i in xrange(4):

  16.        t = threading.Thread(target=run)

  17.        t.start()

運行:

  1. 開始監聽

  2. Connected with 127.0.0.1:61772

  3. GET / HTTP/1.1

  4. Connected with 127.0.0.1:61773

  5. GET / HTTP/1.1

  6. Connected with 127.0.0.1:61774

  7. GET / HTTP/1.1

  8. Connected with 127.0.0.1:61775

  9. GET / HTTP/1.1

UDP編程

UDP與TCP的不同之處在于UDP是不用建立連接的。

在此需要使用s.recvfrom()與s.sendto()方法,前者與s.recv()相同,但返回(data, addr)的元組,addr為數據發送端的套接字地址,后者發送數據時需要加入要發送的遠程地址。

服務器:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

  4. s.bind(('', 10000))

  5. while True:

  6.    data, addr = s.recvfrom(1024)

  7.    print '接收到%s的連接'%str(addr)

  8.    s.sendto(data, addr)

客戶端:

  1. # -*- coding: utf-8 -*-

  2. import socket

  3. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

  4. s.sendto('Hello World', ('localhost', 10000))

  5. r, addr = s.recvfrom(1024)

  6. print r

  7. s.close()

運行:

  1. >>>

  2. 接收到('127.0.0.1', 64112)的連接

  3. >>>

  4. Hello World

預約申請免費試聽課

填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

上一篇:Python 的這些特性,很多老司機都不知道
下一篇:Python局部變量和全局變量6個知識點

哪些崗位學了Python更有優勢?

Python中字符串的處理技巧有哪些

零基礎學Python要掌握的小技巧

Python編程中常見的錯誤有哪些?

選擇城市和中心
黑龍江省

吉林省

河北省

湖南省

貴州省

云南省

廣西省

海南省

4438全国大成网人网站