• <nav id="wias0"><center id="wias0"></center></nav>
  • 更多課程 選擇中心

    Python培訓
    達內IT學院

    400-111-8989

    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的10個知識點

    Python好就業嗎?就業方向哪個好?

    Python制作二維碼真的這么簡單?

    5個Python概念新手必須了解!

    選擇城市和中心
    黑龍江省

    吉林省

    河北省

    湖南省

    貴州省

    云南省

    廣西省

    海南省

    4438全国大成网人网站