Python網絡編程

網絡編程

# notes 要點
網絡編程

客戶端/服務器架構

客戶端/服務器網絡編程

套接字是計算機網絡數據結構。在任何類型的通信開始之前,網絡應用程序必須創建套接字。可以將它們比作電話插孔,沒有它將無法進行通信。

進程間通信(Inter Process Communication)

地址家族(address family):
UNIX套接字: AF_UNIX (基於文件)
INET套接字: AF_INET (基於網絡)(因特網)

套接字地址:主機-端口對

面向連接的套接字:通信之前必須先建立一個連接(提供序列化的、可靠的和不重複的數據交付,而沒有記錄邊界)
實現這種連接類型的主要協議是傳輸控制協議(Transmission Control Protocol)(TCP)
為了創建TCP套接字,必須使用SOCK_STREAM作為套接字類型

無連接的套接字:在通信開始前不需要建立連接(無法保證順序性、可靠性或重複性)
實現這種連接類型的主要協議是用戶數據報協議(User Datagram Protocol)(UDP)
為了創建UDP套接字,必須哈斯用SOCK_DGRAM作為套接字類型

 

# sock.py python中的網絡編程-socket篇

# 要創建套接字,必須使用socket.socket(socket_family, socket_type, protocol=0)
# socket_family 地址家族 AF_UNIX或AF_INET 
# socket_type 套接字類型 SOCK_STREAM或SOCK_DGRAM
# protocol通常省略,默認為0

# 為了創建TCP/IP套接字
# tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 為了創建UDP/IP套接字
# udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 套接字對象(內置)方法
# 服務器套接字方法
# s.bind()        將地址(主機名,端口號對)綁定到套接字上
# s.listen()    設置並啟動TCP監聽器
# s.accept()    被動接受TCP客戶端鏈接,一直等待直到連接到達(阻塞)

# 客戶端套接字方法
# s.connect()    主動發起TCP服務器連接
# s.connect_ex()擴展版本,以錯誤碼形式返回問題,而不是拋出一個異常

# 普通的套接字方法
# s.recv()        接受TCP信息
# s.recv_into()    接受TCP信息到指定的緩衝區
# s.send()         發送TCP信息
# s.sendall()    完整地發送TCP信息

# 創建TCP服務器
# ss = socket()             創建服務器套接字
# ss.bind()                    套接字與地址綁定
# ss.listen()                監聽連接
# inf_loop:                    服務器無限循環
#     cs = ss.accept()        接受客戶端連接(返回客戶端套接字)
#     comm_loop:                通信循環
#         cs.recv()/cs.send() 對話(接受/發送)
#     cs.close()                關閉客戶端套接字
# ss.close()                關閉服務器套接字

# 創建TCP客戶端
# cs = socket()                創建客戶端套接字
# cs.connect()                嘗試連接服務器
# comm_loop:                通信循環
#     cs.send()/cs.recv()        對話(發送/接受)
# cs.close()                關閉客戶端套接字

# 創建UDP服務器
# ss = socket()                創建服務器套接字
# ss.bind()                    綁定服務器套接字
# inf_loop():                服務器無線循環
#     cs = ss.recvfrom()/ss.sendto()    # 關閉(接受/發送)
# ss.close()

# 創建UDP客戶端
# cs = socket()                創建客戶端套接字
# comm_loop:                通信循環
#     cs.sendto()/cs.recvfrom()    對話(發送/接受)
# cs.close()                關閉客戶端套接字

 

# tcpServer.py TCP服務端
#!/usr/bin/env python

from socket import *
from time import ctime

HOST = ''              # 主機名
PORT = 31416        # 端口
BUFSIZ = 1024        # 緩衝大小
ADDR = (HOST, PORT) # 套接字地址(主機名,端口)

tcpSerSock = socket(AF_INET, SOCK_STREAM)  # 創建套接字
tcpSerSock.bind(ADDR)  # 套接字與地址綁定
tcpSerSock.listen(5)  # 監聽

try:
    while True:
        print('waiting for connection...')
        tcpCliSock, addr = tcpSerSock.accept()  # 阻塞,等待連接,返回客戶端套接字與套接字地址(主機名,端口)
        print('...connected from:', addr)

        while True:
            data = tcpCliSock.recv(BUFSIZ)
            if not data:
                break
            reply = '[%s] %s' % (ctime(), data.decode('utf-8'))
            tcpCliSock.send(bytes(reply, 'utf-8'))
        tcpCliSock.close()
    tcpSerSock.close()
except KeyboardInterrupt:
    print('Bye!')
  
# tcpClient.py TCP客戶端
#!/usr/bin/env python

from socket import *

HOST = 'localhost' # or 'localhost'
PORT = 31416
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

while True:
    data = input('> ')
    if not data:
        break
    tcpCliSock.send(bytes(data, 'utf-8'))
    data = tcpCliSock.recv(BUFSIZ)
    if not data:
        break
    print(data.decode('utf-8'))

tcpCliSock.close()

 

# udpServer.py UDP服務端
#!/usr/bin/env python

from socket import *
from time import ctime

HOST = ''
PORT = 31416
BUFSIZ = 1024
ADDR = (HOST, PORT)

udpSerSock = socket(AF_INET, SOCK_DGRAM)
udpSerSock.bind(ADDR)

try:
    while True:
        print('waiting for massage...')
        data, addr = udpSerSock.recvfrom(BUFSIZ)
        reply = '[%s]: %s' % (ctime(), data.decode('utf-8'))
        udpSerSock.sendto(bytes(reply, 'utf-8'), addr)
        print('...received from and returned to:', addr)
except KeyboardInterrupt:
    print('Bye!')

udpSerSock.close()
# udpClient.py UDP客戶端
#!/usr/bin/env python

from socket import *

HOST = 'localhost'
PORT = 31416
BUFSIZ = 1024
ADDR = (HOST, PORT)

udpCliSock = socket(AF_INET, SOCK_DGRAM)

while True:
    data = input('> ')
    if not data:
        break
    udpCliSock.sendto(bytes(data, 'utf-8'), ADDR)
    data, ADDR = udpCliSock.recvfrom(BUFSIZ)
    if not data:
        break
    print(data.decode('utf-8'))

udpCliSock.close()

 

《Python網絡編程》

 

 

# tcpSocketServer.py SocketServerTCP服務器
#!/usr/bin/env python

from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)
from time import ctime

HOST = ''
PORT = 31416
ADDR = (HOST, PORT)

class MyRequestHandler(SRH):
    def handle(self):
        print('...connected from:', self.client_address)
        reply = '[%s] %s' % (ctime(), self.rfile.readline().decode('utf-8'))
        self.wfile.write(bytes(reply, 'utf-8'))

tcpServ = TCP(ADDR, MyRequestHandler)
print('waiting for connection...')
tcpServ.serve_forever()
# tcpSocketClient.py SocketServerTCP客戶端
#!/usr/bin/env python

from socket import *

HOST = 'localhost'
PORT = 31416
BUFSIZ = 1024
ADDR = (HOST, PORT)

while True:
    # socketserver處理程序的默認行為是接受連接、獲取請求,然後關閉連接,所以,每次都要新建一個套接字    tcpCliSock = socket(AF_INET, SOCK_STREAM)
    tcpCliSock.connect(ADDR)
    data = input('> ')
    if not data:
        break
    reply = '%s\r\n' % data
    tcpCliSock.send(bytes(reply, 'utf-8'))  # 因為這裏使用的處理程序類對待套接字通信就像文件一樣,所以必須發送終止符(回車和換行符)
    data = tcpCliSock.recv(BUFSIZ)
    if not data:
        break
    print(data.decode('utf-8').strip())
    tcpCliSock.close()

 

《Python網絡編程》

 

点赞

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *