Day 33 Socket编程.
套接字 (socket)处使用
基于TCP 协议的套接字
TCP 是基于链接的 ,服务器端和客户端启动没有顺序.
服务器端设置:
import socket sk =socket.socket() # 1. 实例化 sk.bind(('127.0.0.1',8081))#把地址绑定到套接字 #2. bind sk.listen()#监听链接 #3.监听 conn,addr = sk.accept()#接收客户端链接 #4.接收链接 ret =conn.recv((1024))#接收客户端信息 #5. 接收信息
print(ret) conn.send(b'hello_world')#向客户端发送信息. #6.发消息 conn.close()#关闭链接 sk.close()#关闭服务器套接字,可选
输出结果 :b'hellow iam the client side !'
客户端配置:
import socket sk =socket.socket() #创建客户套接字 1.实例化 sk.connect(('127.0.0.1',8080)) #尝试链接服务器 #2.连接 sk.send(b'hellow iam the client side !') #3. 发送 ret =sk.recv(1024) #4.接收 print(ret) sk.close()#关闭客户套接字.
输出结果:b'hello_world'
问题:有的同学在重启服务端时可能会遇到
解决办法
import socket from socket import SOL_SOCKET,SO_REUSEADDR sk =socket.socket() sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#在bind前绑定. sk.bind(('127.0.0.1',8081))#把地址绑定到套接字 sk.listen()#监听链接 conn,addr = sk.accept()#接收客户端链接 ret =conn.recv((1024))#接收客户端信息 print(ret) conn.send(b'hello_world')#向客户端发送信息. conn.close()#关闭链接 sk.close()#关闭服务器套接字,可选
基于UDP的套接字协议
upd是面向无连接的,启动服务后可以直接接受消息,不需要提前建立链接
Server端
import socket udp_sk = socket.socket(type=socket.SOCK_DGRAM) #1. 实例化 udp_sk.bind(('127.0.0.1',9002)) #2.bind 地址与端口 msg,addr = udp_sk.recvfrom(1024) #3. 接收消息. print(msg) udp_sk.sendto(b'hello iam the serverside',addr) #4.发送消息. udp_sk.close()
输出结果:
client端
import socket ip_port =('127.0.0.1',9002) udp_sk =socket.socket(type=socket.SOCK_DGRAM) #1.实例化 udp_sk.sendto(b'hello',ip_port) #2.发送 msg,addr=udp_sk.recvfrom(1024) #3.接收 print(msg)
输出结果 b'hello iam the serverside'
TCP 聊天小工具
服务器端
import socket sk =socket.socket() sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) sk.bind(('192.168.21.36',9090)) sk.listen() while True: con,addr =sk.accept()#接收连接,三次握手conn while True: inp = input('请输入') if inp =='q': con.send(inp.encode('utf-8')) break con.send(inp.encode('utf-8')) msg =con.recv(1024) if msg ==b'q':break print(msg.decode('utf-8')) con.close() sk.close()
客户端:
import socket sk = socket.socket() sk.connect(('127.0.0.1',9000)) while True: msg = sk.recv(1024) print(msg.decode('utf-8')) if msg == b'q':break inp = input('>>>') if inp == 'q': sk.send(inp.encode('utf-8')) break sk.send(inp.encode('utf-8')) sk.close()
UDP 聊天小工具
服务器端
import socket
sk = socket.socket(type=socket.SOCK_DGRAM) # 建立一个socket对象,
# 指定以UDP协议的形式来连接
sk.bind(('127.0.0.1',8080))
# 指定服务的地址
msg,addr = sk.recvfrom(1024) # 接收消息,发送端的地址
print(msg,addr)
sk.sendto(b'HELLO',addr) # 给发送端回复消息
sk.close() # 关闭socket连接
客户端
import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.sendto(b'hello',('127.0.0.1',8080)) # 直接给服务器发送一段消息 msg,addr = sk.recvfrom(1024) # 接收对面的回信 print(msg) sk.close()
时钟同步试题
服务器端
import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.sendto(b'hello',('127.0.0.1',8080)) # 直接给服务器发送一段消息 msg,addr = sk.recvfrom(1024) # 接收对面的回信 print(msg) sk.close()
客户端
# client端每隔一段时间发送请求到服务端 # 发送时间的格式 import time import socket sk = socket.socket(type = socket.SOCK_DGRAM) sk.sendto('%Y-%m-%d %H:%M:%S'.encode('utf-8'),('127.0.0.1',9000)) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) sk.close() # 方式一 # 操作系统的定时任务 + python代码的形式 # 方式二 # while True + time.sleep的形式