day31
第一步骤:
socket服务端
import socket
# 作为服务器必明确自己的ip和端口号 并且不应该变化
# 参数1指定 socket类型AF_INET 表示网络类型
#参数2指定的传输协议为 SOCK_STREAM表示TCP协议 SOCK_DGRAM UDP协议
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 1.买电话机
# 默认就是网络类型 TCP协议
#server = socket.socket()
# 127.0.0.1这叫回送地址 表示当前电脑本身
# ip一定本机ip 本机可能会有多个IP (无线|有限)
# 注意:需要参数是一个元组 端口就是普通整数
server.bind(("127.0.0.1",1688)) # 2.插入手机卡
# 无论是服务器端还是客户端 都是socket 类型
# 开始监听1688端口 盯着这个端口看以后没有数据过来
server.listen() # 3.手机开始待机
# 接收链接请求
# 第一个是表示客户端的socket 第二个客户端的地址信息
client,addr = server.accept() # 4.接电话
# print(type(client))
# print(addr)
# 5.收发数据
data = client.recv(1024)
print(data)
client.send("copy!".encode("utf-8"))
server.close() # 关机
socket客户端
import socket
# 买个电话
client = socket.socket()
# 作为客户端 ip和端口可以变化 所有系统会自动分配随机端给客户端
client.connect(("127.0.0.1",1688))
# 开始通话
# 发送数据 注意发送的内容只能是二进制 bytes
client.send("hello".encode("utf-8"))
# 接收数据 单位为字节
data = client.recv(1024)
print(data)
client.close()
#######################################################
第二步骤:windows正常关闭
服务端
import socket
server = socket.socket()
server.bind(("127.0.0.1",8989))
server.listen()
while True:
client_socket,client_addr = server.accept()
buffer_size = 1024 #缓冲区 就是一个临时的容器
# 缓冲区大小 不能随便写 太大会导致内存溢出 太小效率低 在内存能够承受的情况下 大一些
while True:
try:
data = client_socket.recv(1024)
# 在linux中 对方如果强行下线了 服务器不会抛出异常 只会收到空消息
# 得加上判断 如果为空则意味着 对方下线了 应该关闭链接 跳出循环
if not data:
client_socket.close()
break
print("收到数据:",data.decode("utf-8")) # 解码时必须保证双方同意编码方式
# 转为大写在发回去
client_socket.send(data.upper())
except ConnectionResetError as e:
print("%s %s" % (client_addr[0],client_addr[1]),e)
# 如果对方下线了 那服务器也应该关闭对应的客户端对象
client_socket.close()
break
# 通常服务器不会关闭
# server.close()
客户端
import socket
client = socket.socket()
# 指定服务器的端口和ip 客户端的端口系统自动分配的
client.connect(("127.0.0.1",8989)) #
# 添加循环 用来重复收发数据
while True:
# 收发的顺序 必须很对面相反 否则卡死了
msg = input("输入内容:(q:退出)")
if msg == "q":break
if not msg:continue
client.send(msg.encode("utf-8"))
print("sended!")
data = client.recv(1024)
print(data.decode("utf-8"))
client.close()
#############################################
常见的异常
import socket
server = socket.socket()
server.bind(("127.0.0.1",8888)) # 只有服务器需要绑定
server.listen()
# accept 是一个阻塞函数 会一直等到有客户端链接过来 在继续执行
client,addr = server.accept() # 完成了三次握手
# print(client)
# print(addr)
print("握手成功!")
# 收发数据 注意都是用表示客户端的socket来收发数据
# client.send("world".encode("utf-8"))
import time
time.sleep(3)
try:
# data = client.recv(1024)
# print("客户端发来的数据:", data)
# 发送数据时 对方可能也会异常下线 也会抛出异常
# 接收数据 和发送数据都应该放到try
client.send("test".encode("utf-8"))
except:
print("client 下线了")
# 断开链接
client.close() # 完成四次挥手
server.close()
print("服务器关机!")
客户端
import socket
client = socket.socket()
# connect本质实在进行三次握手 也是一个数据传输的过程 如果服务器没有立马响应 也会阻塞
#
client.connect(("127.0.0.1",8888)) # 三次握手
print("握手成功! client")
# 发送数据 本质上是把数据交给操作系统来进行发送 一旦数据交给了操作系统 后续的发送
# 应用程序就无法控制了 ,send一般不会卡 当然 如果数据量很大就会阻塞
# client.send("hello".encode("utf-8"))
# print("发送完成")
# 是从操作系统缓存区读取数据 如果当前还没有任何数据 就会进入阻塞
# 会一直等到有数据到来 再继续执行
# try:
# data = client.recv(1024)
# print("接收完成!")
# print(data)
# except:
# print("服务器 强行下线了!")
import time
time.sleep(10)
# 客户端执行close 是正常关闭链接 会给服务器送空字节 用于表示要断开链接
client.close()
print("关机了!")
端口占用的问题
import socket
server = socket.socket()
server.bind(("127.0.0.1",9891))
server.listen()
server.accept()
server.close()
# 如果已经开启了服务器 再次运行将会抛出 端口占用异常 把之前开启的服务器关掉即可
"""
有些情况 明明已经关闭了进程 但是 还是端口占用
可能是进程正在后台运行 可以通过端口查出进程 进行关闭
windows下
netstat -ano | findstr 9898
tasklist | findstr 进程id 拿到进程名称
taskkill /f /t /im 进程名称
大招: 重启电脑
"""
##############################################
循环模板
服务器
import socket
server = socket.socket()
server.bind(("127.0.0.1",8989))
server.listen()
while True:
client_socket,client_addr = server.accept()
buffer_size = 1024 #缓冲区 就是一个临时的容器
# 缓冲区大小 不能随便写 太大会导致内存溢出 太小效率低 在内存能够承受的情况下 大一些
while True:
try:
data = client_socket.recv(1024)
# 在linux中 对方如果强行下线了 服务器不会抛出异常 只会收到空消息
# 得加上判断 如果为空则意味着 对方下线了 应该关闭链接 跳出循环
# windows上正常关闭 也会收到空消息 if 必须要加
if not data:
client_socket.close()
break
print(data.decode("utf-8")) # 解码时必须保证双方同意编码方式
# 转为大写在发回去
client_socket.send(data.upper())
except ConnectionResetError as e:
print("%s %s" % (client_addr[0],client_addr[1]),e)
# 如果对方下线了 那服务器也应该关闭对应的客户端对象
client_socket.close()
break
# 通常服务器不会关闭
# server.close()
客户端
import socket
client = socket.socket()
# 指定服务器的端口和ip 客户端的端口系统自动分配的
client.connect(("127.0.0.1",8989)) #
# 添加循环 用来重复收发数据
while True:
# 收发的顺序 必须很对面相反 否则卡死了
msg = input("输入内容:")
if not msg:continue
client.send(msg.encode("utf-8"))
print("sended!")
data = client.recv(1024)
print(data.decode("utf-8"))
client.close()