TCP客户端
import socket
c = socket.socket()
# 连接服务器
c.connect(("127.0.0.1",65535))
while True:
# 发送数据
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8"))
print("send!")
# # 收数据
data = c.recv(1024).decode("utf-8")
print("receiver!")
print(data)
# 关闭资源
c.close()
TCP服务器
import socket
# 使用TCP 可以直接默认
server = socket.socket()
# 指定端口 和 ip 端口 0 - 1023是系统保留的
server.bind(("127.0.0.1",65535))
# 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen(5)
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 1024 程序的最大缓冲区容量 返回值类型为bytes类型
data = c.recv(1024).decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为kong 此时应该结束循环
if not data:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(data)
# 回复数据 将原始数据转为大写
c.send(data.upper().encode("utf-8"))
except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close()
# TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close
CMD客户端
import socket
c = socket.socket()
# 连接服务器
c.connect(("127.0.0.1",65535))
while True:
# 发送数据
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8"))
# while True:
# # 收数据
data = c.recv(1024).decode("gbk")
print(data)
# 关闭资源
c.close()
# 问题? 服务器发送的数据超过了接收端缓冲区大小 可直接修改大小来满足服务器传输的大小 但是不长远
# 上述问题 称之为粘包
# 思考: 循环每次读取一小部分 直到取完为止
# 什么时候可以结束循环 前提是让客户端直知道你的数据到底有多长
# 正确思路:
"""
发送方
1.先告诉对方你要发的数据的长度
2.在发送真实数据
接收方
1.先接收数据的长度信息
2.根据长度信息循环获取直到以获取的长度等于总长度
"""
CMD客户端2
import socket,time
c = socket.socket()
# 连接服务器
c.connect(("127.0.0.1",65535))
while True:
# 发送数据
c.send("dir".encode("utf-8"))
time.sleep(1)
c.send("dir".encode("utf-8"))
data = c.recv(1024).decode("gbk")
print(data)
# 关闭资源
c.close()
# 问题2 当客户端连续两行代码都发送一个dir时 服务器收到了一个dirdir
# 两个命令黏在一起
# TCP协议内的一个nagle算法 如果数据量小 并且时间间隔短会将数据合并一个包
CMD服务器
# 1.服务器先启动 -> 客户端发送指令 -> 服务器接收后使用subprocess执行命令->将执行结果返回给客户端
import socket,subprocess
# 使用TCP 可以直接默认
server = socket.socket()
# 指定端口 和 ip 端口 0 - 1023是系统保留的
server.bind(("127.0.0.1",65535))
# 监听请求 参数为最大半连接数(三次握手未完成的请求 可能是服务器来不及 客户端恶意攻击)
server.listen(5)
# 为了可以不断的接受客户端连接请求
while True:
# 接受连接请求
c,addr = server.accept()
# 为了可以重复收发数据
while True:
try:
# 1024 程序的最大缓冲区容量 返回值类型为bytes类型
cmd = c.recv(1024).decode("utf-8")
# 如果客户端断开连接(客户端调用了close) recv 返回值为kong 此时应该结束循环
if not cmd:# 在linux中 客户端异常关闭 服务器也会收空
print("client closed!")
c.close()
break
#解码
print(cmd)
# 执行命令
p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# 将错误信息和正确信息拼接到一起
res = p.stdout.read() + p.stderr.read()
print("执行结果长",len(res))
# 将执行结果发送给客户端
c.send(res)
except ConnectionResetError:
print("客户端异常关闭!!")
c.close()
break
# 关闭资源
server.close()
# TCP断开连接的正确姿势
# 客户端调用close
# 服务器判断如果接收数据为空则相应的调用close
解决粘包问题
import struct
# 整型转字节 i 表示int 长度为4字节 q表示long int 长度为8字节
print(len(struct.pack("q",10240000000)))
# 字节转整型 得到一个元祖
print(struct.unpack("q",struct.pack("q",10240000000))[0])