网络知识补充
1、CS架构与BS架构
CS:客户端,服务端
BS:浏览器,服务器
2、tcp 三次握手,四次挥手
![img](https://images2015.cnblogs.com/blog/1036857/201610/1036857-20161008185648160-191189690.png)
3、数据包传输过程
![img](https://img2020.cnblogs.com/blog/1036857/202004/1036857-20200415215541847-564448301.gif)
基于TCP协议的套接字
server端:
from socket import *
phone = socket(AF_INET,SOCK_STREAM) #创建服务器套接字
phone.bind(('127.0.0.1',8899)) #把地址绑定到套接字
phone.listen(5) #监听链接,括号内为指定半连接数
while True:
conn,client_add = phone.accept() #接受客户端链接,conn表示连接,client表示客户端ip和端口
print(conn)
print('客户端的ip和端口',client_add)
#conn.close() #关闭当前连接
#phone.close() # 关闭套接字服务器
client端:
from socket import *
phone = socket(AF_INET,SOCK_STREAM) #创建服务器套接字
phone.connect(('127.0.0.1',8899)) #设置连接地址
while True:
msg = input('请输入命令:').strip()
if len(msg) == 0:
continue
phone.send(msg.encode('utf-8')) #设置发送的数据
data = phone.recv(1024) #设置接收的数据
print('接收到服务器发来的:',data.decode('utf-8'))
phone.close() #关闭当前连接
基于UDP协议的套接字
服务器:
from socket import *
phone = socket(AF_INET,SOCK_DGRAM)
while True:
choice = input('请输入传输内容:').strip()
phone.sendto(choice.encode('utf-8'),('127.0.0.1',8081))
func=phone.recv(1024)
print(func.decode('utf-8'))
# phone.close()
客户端
from socket import *
phone = socket(AF_INET,SOCK_DGRAM)
while True:
choice = input('请输入传输内容:').strip()
phone.sendto(choice.encode('utf-8'),('127.0.0.1',8081))
func=phone.recv(1024)
print(func.decode('utf-8'))
# phone.close()
TCP沾包问题 and 远程执行命令功能
服务端:
import json
import struct
from socket import *
import subprocess
import string
import _json
phone = socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',8899))
phone.listen(5)
while True:
conn,client_add = phone.accept()
while True:
try:
cmd = conn.recv(1024)
if len(cmd) ==0:
break
obj = subprocess.Popen(
cmd.decode('utf-8'),
shell = True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
stdout_res = obj.stdout.read()
stderr_res = obj.stderr.read()
total_size = len(stderr_res) + len(stdout_res)
header_dir = {
"filename":'a.txt',
"total_size":total_size,
"md5":'123123ass123'
}
#服务端:
#1、制作头
# 将字典转化成json格式的字符串,然后在转化为bytes,然后将其打入到header_size里
json_str = json.dumps(header_dir)
json_str_bytes = json_str.encode('utf-8')
x = struct.pack('i',len(json_str_bytes))
#2、将头的长度发送过去
conn.send(x)
#3、传输头信息
conn.send(json_str_bytes)
#4、最后发送真时数据
conn.send(stdout_res)
conn.send(stderr_res)
#接收端
#1、先收4个字,从中提取下来要收的头的长度
#2、json_str_bytes = recv (头的长度)
# json_str=json_str_bytes.decode('utf-8')
# header_dic = json.loads(json_str)
# print(header_dic)
# total_size = header_dic["total_size"]
#3、接收真正的数据
except Exception:
break
# conn.close()
客户端:
import struct
from socket import *
import json
client = socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8899))
while True:
cmd = input('请输入命令:').strip()
if len(cmd) == 0:
continue
client.send(cmd.encode('utf-8'))
# 1、先收4个字,从中提取下来要收的头的长度
x=client.recv(4)
if not len(x) == 4:
continue
header_len = struct.unpack('i',x)[0] #将拿到的4个集字节进行反解
# 2、接收头并解析
json_str_bytes = client.recv (header_len)
json_str=json_str_bytes.decode('utf-8')
header_dic = json.loads(json_str)
print(header_dic)
total_size = header_dic["total_size"]
# 3、接收真正的数据
recv_size = 0
while recv_size < total_size:
recv_data = client.recv(1024)
recv_size += len(recv_data)
print(recv_data.decode('gbk'),end='')
else:
print()
socketserver多并发
基于TCP
#服务端
import socketserver
class MyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
print(self.request) #如果tcp协议,self.request=>conn
print(self.client_address)
while True:
try:
data = self.request.recv(1024)
if len(data) == 0:
break
self.request.send(data.upper())
except Exception:
break
self.request.close
#相当于循环的从半连接池中取出连接请求建立双向连接,拿到连接对象
s = socketserver.ThreadingTCPServer(('127.0.0.1',8888),MyRequestHandle)
s.serve_forever() #这个函数会建连接,每建立一个连接则生成一个进程来处理
#客户端
from socket import *
phone = socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8888))
while True:
msg = input('请输入命令:').strip()
if len(msg) == 0:
continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print('接收到服务器发来的:',data.decode('utf-8'))
phone.close()
基于UDP
#客户端
from socket import *
phone = socket(AF_INET,SOCK_DGRAM)
while True:
choice = input('请输入传输内容:').strip()
phone.sendto(choice.encode('utf-8'),('127.0.0.1',8888))
func=phone.recvfrom(1024)
print(func)
# phone.close()
#服务端
import socketserver
class MyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
client_data = self.request[0]
server = self.request[1]
client_add = self.client_address
print('客户端发来的数据%s'%client_data)
server.sendto(client_data.upper(),client_add)
s = socketserver.ThreadingUDPServer(('127.0.0.1',8888),MyRequestHandle)
s.serve_forever()
#相当于:只负责循环的收,收到后交给小弟去处理