之前實現了Java版本的TCP和UDP套接字編程的例子,於是決定結合Python的學習做一個Python版本的套接字編程實驗。
流程如下:
1.一台客戶機從其標准輸入(鍵盤)讀入一行字符,並通過其套接字將該行發送到服務器。
2.服務器從其連接套接字讀取一行字符。
3.服務器將該行字符轉換成大寫。
4.服務器將修改后的字符串(行)通過連接套接字再發回給客戶機。
5.客戶機從其套接字中讀取修改后的行,然后將該行在其標准輸出(監視器)上打印出來。
【TCP】服務器端代碼:
import socket import time import threading s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #創建socket (AF_INET:IPv4, AF_INET6:IPv6) (SOCK_STREAM:面向流的TCP協議) s.bind(('127.0.0.1', 10021)) #綁定本機IP和任意端口(>1024) s.listen(1) #監聽,等待連接的最大數目為1 print('Server is running...') def TCP(sock, addr): #TCP服務器端處理邏輯 print('Accept new connection from %s:%s.' %addr) #接受新的連接請求 while True: data = sock.recv(1024) #接受其數據 time.sleep(1) #延遲 if not data or data.decode() == 'quit': #如果數據為空或者'quit',則退出 break sock.send(data.decode('utf-8').upper().encode()) #發送變成大寫后的數據,需先解碼,再按utf-8編碼, encode()其實就是encode('utf-8') sock.close() #關閉連接 print('Connection from %s:%s closed.' %addr) while True: sock, addr = s.accept() #接收一個新連接 TCP(sock, addr) #處理連接
【TCP】客戶端代碼:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #創建一個socket s.connect(('127.0.0.1', 10021)) #建立連接 while True: #接受多次數據 data = input('請輸入要發送的數據:') #接收數據 if data == 'quit': #如果為'quit',則退出 break s.send(data.encode()) #發送編碼后的數據 print(s.recv(1024).decode('utf-8')) #打印接收到的大寫數據 s.send(b'quit') #放棄連接 s.close() #關閉socket
運行結果:
UDP協議則不需要事先建立連接,直接互相發送數據即可。
【UDP】服務器端代碼:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #創建一個socket,SOCK_DGRAM表示UDP s.bind(('127.0.0.1', 10021)) #綁定IP地址及端口 print('Bound UDP on 10021...') while True: data, addr = s.recvfrom(1024) #獲得數據和客戶端的地址與端口,一次最大接收1024字節 print('Received from %s:%s.' % addr) s.sendto(data.decode('utf-8').upper().encode(), addr)#將數據變成大寫送回客戶端 #不關閉socket
【UDP】客戶端代碼:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) addr = ('127.0.0.1', 10021) #服務器端地址 while True: data = input('請輸入要處理的數據:') #獲得數據 if not data or data == 'quit': break s.sendto(data.encode(), addr) #發送到服務端 recvdata, addr = s.recvfrom(1024) #接收服務器端發來的數據 print(recvdata.decode('utf-8')) #解碼打印 s.close() #關閉socket
運行結果: