簡單的尷聊,實現服務器和客戶端的文字傳輸
###TCP協議狀況算法
#server.py import socket #導入socket模塊 from socket import SOL_SOCKET, SO_REUSEADDR #記住這個模塊 sk = socket.socket() #實例化socket對象 sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) #這行代碼是爲了實現端口繼續利用的 sk.bind(('127.0.0.1', 8080)) #爲sk對象綁定一個ip和一個端口 sk.listen() #啓動監聽 conn, addr = sk.accept() #等待一個客戶端的鏈接 while 1: ret = conn.recv(1024).decode('utf-8') #等待客戶端發送消息 if ret == 'bye': break print(ret) info = input('反饋: ') conn.send(bytes(info, encoding='utf-8')) #向客戶端發動消息 conn.close() sk.close() ___________________________________________________ ___________________________________________________ #client import socket sk = socket.socket() sk.connect(('127.0.0.1', 8080)) while 1: info = input('輸入: ') sk.send(bytes(info, encoding='utf-8')) if info == 'bye': break ret = sk.recv(1024).decode('utf-8') print(ret) sk.close()
###改進版,爲聊天消息加入時間shell
#server import socket from socket import SOL_SOCKET, SO_REUSEADDR from time import ctime, time sk = socket.socket() sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sk.bind(('127.0.0.1', 8080)) sk.listen() conn, addr = sk.accept() while 1: t = ctime(float(conn.recv(1024).decode('utf-8'))) ret = conn.recv(1024).decode('utf-8') if ret == 'bye': break print('{}收到{}'.format(t, ret)) info = input('反饋: ') conn.send(bytes(info, encoding='utf-8')) conn.send(bytes(str(time()), encoding='utf-8')) conn.close() sk.close() ---------------------------------------------- ---------------------------------------------- #client import socket from time import time, ctime sk = socket.socket() sk.connect(('127.0.0.1', 8080)) while 1: info = input('輸入: ') sk.send(bytes(str(time()), encoding='utf-8')) sk.send(bytes(info, encoding='utf-8')) if info == 'bye': break ret = sk.recv(1024).decode('utf-8') t = ctime(float(sk.recv(1024).decode('utf-8'))) print(t, ret) sk.close()
###__UDP協議__狀況服務器
#server #建立一個UDP協議的服務器 import socket sk = socket.socket(type=socket.SOCK_DGRAM) #實例化一個socket對象 sk.bind(('127.0.0.1', 8081)) #給服務器綁定一個ip和端口 conn, addr = sk.recvfrom(1024) #接受消息,接收到消息內容和對方機器地址 print(conn.decode('utf-8'), addr) sk.sendto(b'bye', addr) sk.close() -------------------------------- -------------------------------- #client #建立一個UDP客戶端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) #建立socket對象 ip_port = ('127.0.0.1', 8081) sk.sendto(b'hello', ip_port) conn, addr = sk.recvfrom(1024) print(conn.decode('utf-8'), addr) sk.close()
黏包涉及到TCP協議自帶的拆包機制,一種優化文件傳輸的機制網絡
###黏包出現的兩種狀況每次發送信息以前,先向服務器反饋信息的長度,告知服務器即將接收數據的長度socket
#server import socket from socket import SOL_SOCKET, SO_REUSEADDR sk = socket.socket() sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sk.bind(('127.0.0.1', 8080)) sk.listen() conn, addr = sk.accept() #服務器發送命令 cmd = input('輸入須要發送的命令: ') conn.send(bytes(cmd, encoding='utf-8')) print('命令已經發送!') #接收命令反饋信息的長度 num = int(conn.recv(10).decode('utf-8')) print('接收到長度,長度是{}'.format(num)) #反饋給客戶端已經收到長度信息 conn.send(b'Roger that') #接收命令反饋信息 msg = conn.recv(num).decode('utf-8') print('接收到信息') #打印命令返回信息 print(msg) #反饋信息給客戶端 conn.send(bytes('服務器說:接收完畢', encoding='utf-8')) #關閉服務 conn.close() sk.close() ----------------------------- ----------------------------- #client import socket import subprocess import time sk = socket.socket() sk.connect(('127.0.0.1', 8080)) #接收服務器命令 cmd = sk.recv(1024).decode('utf-8') print(cmd) #將命令傳給控制檯 ret = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print('控制檯已經接收到命令') #將控制檯傳回的信息長度反饋給服務器 std_out = ret.stdout.read() std_err = ret.stderr.read() num = len(std_out) + len(std_err) sk.send(bytes(str(num), encoding='utf-8')) print('控制檯輸出信息的長度已經反饋') #詢問服務器收到長度了不 has_len = sk.recv(1024) print(has_len.decode('utf-8')) #將控制檯傳回的信息內容反饋給服務器 sk.send(std_out) sk.send(std_err) print('控制檯輸出的信息內容已經反饋') #接收服務器反饋的信息 info = sk.recv(1024).decode('utf-8') print(info) #關閉客戶端 sk.close()