import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM) #创建一个服务器的套接字
udp_sk.bind(('127.0.0.1',9000)) #绑定服务器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
udp_sk.sendto(b'hi',addr) # 对话(接收与发送)
udp_sk.close() # 关闭服务器套接字
import socket
ip_port=('127.0.0.1',9000)
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)
import struct
a = 20
b = 400
s = struct.pack('ii', a, b)
print(s, type(s))
#输出:b'\x14\x00\x00\x00\x90\x01\x00\x00' <class 'bytes'>
print('length: ', len(s))
#输出:length: 8
s2 = struct.unpack('ii', s)
print(s2)
#输出:(20, 400)
s2 = struct.unpack('ii', s)
#报错:unpack requires a buffer of 4 bytes
#==>解压需要一个4字节的缓冲区,也就是说'ii'表示8个字节的缓冲
res=subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
的结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码
且只能从管道里读一次结果
注意
当发送端缓冲区的长度大于网卡的MTU时,tcp会将这次发送的数据拆成几个数据包发送出去。
MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。MTU的单位是字节。 大部分网络设备的MTU都是1500。
如果本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度。
import socket
import subprocess
server = socket.socket()
server.bind(('127.0.0.1',8008))
server.listen(5)
while True:
print("server is working.....")
conn,addr = server.accept() #建立链接
# 字节类型
while True:
# 针对window系统
try:
cmd = conn.recv(1024).decode("utf8") # 阻塞
if cmd == b'exit': #判断与客户端链接是否结束
break
res=subprocess.Popen(cmd,
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
)
# print("stdout",res.stdout.read())
# print("stderr",res.stderr.read().decode("gbk"))
out=res.stdout.read()
err=res.stderr.read()
print("out响应长度",len(out)) #输出出来的长度
print("err响应长度",len(err)) #错误的长度
if err:
import struct
header_pack = struct.pack("i", len(err)) #压包
conn.send(header_pack) #发送
conn.send(err) #发送错误信息
else:
#构建报头
import struct
header_pack=struct.pack("i",len(out)) #压包
print("header_pack",header_pack) #压包信息
# # 发送报头
conn.send(str(len(out)).encode("utf8")) #发送压包
# 发送数据
conn.send(out) #发送输出出来的数据
except Exception as e: #错误信息处理
break
conn.close()
服务端
import socket
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',8008))
while 1:
cmd = input("请输入命令:")
sk.send(cmd.encode('utf-8')) # 字节 #发送输出的指令
if cmd=="":
continue
if cmd == 'exit': #判断是否退出
break
data_length=int(sk.recv(1024).decode("utf8")) #接收到的信息
print("data_length",data_length) #打印出来
recv_data_length=0 #接收到的长度
recv_data=b""
while recv_data_length<data_length: #如果接收到的长度小于设定的数据长度,则全输出出来,否则直接输出最大长度
data=sk.recv(1024) #阻塞 设定最大输出长度
recv_data_length+=len(data) #计算数据长度
recv_data+=data
print(recv_data.decode("gbk"))
sk.close()
客户端
import socket
import json
sock = socket.socket()
sock.bind(("192.168.13.226",8080))
sock.listen(5)
while 1:
print("正在等待链接.....")
conn,addr = sock.accept() #建立链接
while 1:
data = conn.recv(1024).decode("utf8") #接收数据,并解码
file_info = json.loads(data)
print("file_info",file_info) #查看反序列化出来的是什么
#文件信息
action = file_info.get("action")
filename = file_info.get("filename")
filesize = file_info.get("filesize")
conn.send(b"200") #告诉客户端,我已准备接收数据
#接收文件数据
with open("put/" + filename,"wb") as f:
recv_data_length = 0
while recv_data_length < filesize:
data = conn.recv(1024)
recv_data_length += len(data)
f.write(data)
print("总文件大小为%s,已接收%s"% (filesize,recv_data_length))
print("接收成功! ")
服务端
import socket
import os
import json
sock = socket.socket()
sock.connect(("192.168.13.226",8080))
while 1:
cmd = input("请输入命令:") #put 111.jpg
action,filename = cmd.strip().split(" ")
filesize = os.path.getsize(filename)
file_info = {
"action":action, #命令
"filename":filename, #文件名字
"filesize":filesize #文件大小
}
file_info_json = json.dumps(file_info).encode("utf8") #将字典序列化
sock.send(file_info_json) #发送序列化后的字典
#确认服务端接收到了文件信息
code = sock.recv(1024).decode("utf8")
if code == "200": #服务端已准备接收文件
#发送文件数据
with open(filename,"rb")as f:
for line in f: #把文件一行一行的发过去
sock.send(line)
else:
print("服务器异常! ")
客户端
import hashlib
md5=hashlib.md5()
md5.update(b"hello")
md5.update(b"yuan")
print(md5.hexdigest())
print(len(md5.hexdigest()))
#helloyuan: d843cc930aa76f7799bba1780f578439
# d843cc930aa76f7799bba1780f578439
import struct
import socket
import json
import hashlib
sock = socket.socket()
sock.bind(("127.0.0.1",8080))
sock.listen(5)
while 1:
print("正在等待连接.....")
conn,addr = sock.accept()
while 1:
#接收json的打包长度
file_info_length_pack = conn.recv(4)
file_info_length = struct.unpack("i",file_info_length_pack)[0] #解包
#接收json字符串
file_info_json = conn.recv(file_info_length).decode("utf8")
file_info = json.loads(file_info_json) #反序列化
action = file_info.get("action")
filename = file_info.get("filename")
filesize = file_info.get("filesize")
#循环接收文件
md5 = hashlib.md5()
with open("put/"+ filename,"wb") as f:
recv_data_length = 0
while recv_data_length < filesize:
data = conn.recv(1024)
recv_data_length += len(data)
f.write(data)
#MD5摘要
md5.update(data) #写入要加密的的东西
print("文件总大小:%s,已成功接收%s"% (filesize,recv_data_length))
print("接收成功!")
conn.send(b"OK")
print(md5.hexdigest())
md5_val = md5.hexdigest() #解密
client_md5 = conn.recv(1024).decode('utf8')
if md5_val == client_md5:
conn.send(b"203")
else:
conn.send(b"204")
服务端
import socket
import os
import json
import struct
import hashlib
sock = socket.socket()
sock.connect(("127.0.0.1",8080))
while 1:
cmd = input("请输入命令:") #put 111.jpg
action,filename = cmd.strip().split(" ")
filesize = os.path.getsize(filename) #获取文件大小
file_info = {
"action":action, #命令
"filename":filename,#名字
"filesize":filesize,#文件大小
}
#将file_info字典先序列化,再编码赋值给file_info_json
file_info_json = json.dumps(file_info).encode("utf8")
#打包
ret = struct.pack("i",len(file_info_json))
#发送file_info_json的打包长度
sock.send(ret)
#发送 file_info_json字节串
sock.send(file_info_json)
#发送 文件数据
md5 = hashlib.md5()
with open(filename,"rb") as f:
for line in f:
sock.send(line)
md5.update(line) #写入要加密的东西
data = sock.recv(1024)
print(md5.hexdigest())
md5_val = md5.hexdigest() #获取密文
sock.send(md5_val.encode("utf8"))
is_valid = sock.recv(1024).decode("utf8")
if is_valid == "203":
print("文件完整!")
else:
print("文件上传失败!")
客户端