基于TCP协议和UDP协议的socket套接字使用
一,基于TCP协议socket使用:
server端
import socket server = socket.socket() server.bind(('127.0.0.1',8080)) #绑定IP地址和端口号 server.listen(5) #设置监听数 while True: conn,addr = server.accpet() #建立通道 while True: try: data = conn.recv(1024) #接受客户端消息 if len(data) == 0:break data = data.decode('utf-8') #解码接受到的消息 conn.send(b'hi') except ConnectionResetError: break conn.colse()
client端 import socket client = socket.socket client.connet(('127.0.0.1',8080))#连接服务器 while True: msg = input('>>>>:').encode('utf-8') if len(msg) == 0:continue client.send(msg)#发送消息 data = client.recv(1024)
二,基于UDP协议使用socket
server 端
import socket udp_sk = socket.socket(type=socket.SOCK_DGRAM) #创建一个服务器的套接字 udp_sk.bind(('127.0.0.1',8080)) #绑定服务器套接字 msg,addr = udp_sk.recvfrom(1024) print(msg) udp_sk.sendto(b'hi',addr) # 对话(接收与发送) udp_sk.close() # 关闭服务器套接字
client端
import socket ip_port=('127.0.0.1',8080) udp_sk=socket.socket(type=socket.SOCK_DGRAM) udp_sk.sendto(b'hello',ip_port) back_msg,addr=udp_sk.recvfrom(1024) print(back_msg.decode('utf-8'),addr)
三,TCP协议中的粘包问题:
我们可以使用struct模块来做个报头解决这个问题:
客户端 import socket,time s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) res=s.connect_ex(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if len(msg) == 0:continue if msg == 'quit':break s.send(msg.encode('utf-8')) length=int(s.recv(1024).decode('utf-8')) s.send('recv_ready'.encode('utf-8')) send_size=0 recv_size=0 data=b'' while recv_size < length: data+=s.recv(1024) recv_size+=len(data) print(data.decode('utf-8'))
服务端 import socket,subprocess ip_port=('127.0.0.1',8080) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(ip_port) s.listen(5) while True: conn,addr=s.accept() print('客户端',addr) while True: msg=conn.recv(1024) if not msg:break res=subprocess.Popen(msg.decode('utf-8'),shell=True,\ stdin=subprocess.PIPE,\ stderr=subprocess.PIPE,\ stdout=subprocess.PIPE) err=res.stderr.read() if err: ret=err else: ret=res.stdout.read() data_length=len(ret) conn.send(str(data_length).encode('utf-8')) data=conn.recv(1024).decode('utf-8') if data == 'recv_ready': conn.sendall(ret) conn.close()