自定义协议解决粘包问题,阿里云部署,udp协议套接字,socketserver模块的使用

一:粘包问题解决

1.tcp流式协议

(1)粘包原因是底层的算法决定的,设计原因就是提升的效率,tcp流式协议会将时间间隔短,数据量小的字节 合到一起再去发送的。

(2)只有tcp流式协议才会有粘包现象,udp协议压根没有粘包此说

(3)发收数据是发给操作系统的接口的缓存,再送到对方的操作系统

(4)不是一个send唯一对应一个recv

 

2.模块struct的用法:

import struct,json
header_dic={
'filename':'a.tat',
'total_size':100,
'md5':45612
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
header=struct.pack('i',14873) #i是int类型
print(header) #结果是:'\xd9\x90\x16\x00'
print(len(header))
total_size=struct.unpack('i',header)[0] #不加[0]结果会是:1478873,

print(total_size)

结果是:

b'\x19:\x00\x00'
4
14873

 

 

 

 

3.解决粘包的方法

服务端:

import subprocess
from socket import *
import struct,json

#1买手机
phone=socket(AF_INET,SOCK_STREAM)

#phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR)
#2绑定银行卡
phone.bind(('127.0.0.1',8081)) #元组内放自己的ip地址
#再次启动服务端,告诉端口已经占用,解决办法有:1.换个端口,8080换掉同时客户端也需要换掉 2.在绑定之前加上下面内容:phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR)
# 防止位置在 #2绑定银行卡 上面

#3开机
phone.listen(5)  #半连接池,5以内接受访问请求。  5是访问数量,也就是说除了正在访问的这个,最多再有5个

#4建立链接的请求
while True:       #需要一个循环不停地与客户端交互
    connect,client=phone.accept()
    print(client)

# 5 收/发消息
    while True:
        try:                           #避免客户端突然中断,不会造成服务端崩溃,针对Windows
            date=connect.recv(1024)    #此处的connect 是 connect,client=phone.accept() 处的,1024是最大的接受字节数
            if len(date)==0:           #针对linux系统的
                break
            cmd=date.decode('utf-8')
            obj=subprocess.Popen(cmd,shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            res1=obj.stdout.read()
            res2=obj.stderr.read()

            head_dic={
                'filename':'a.txt',
                'total_size':len(res1)+len(res2),
                'md5':'12345dvxvvv'
            }
            header_json=json.dumps(head_dic)
            head_bytes=header_json.encode('utf-8')

            #先发4个字节
            connect.send(struct.pack('i',len(head_bytes)))   #字节长度是4个
            #再发报头字典
            connect.send(head_bytes)
            #再发真正的数据
            connect.send(res1)
            connect.send(res2)
        except Exception:
            break
    connect.close()

 

客户端:


import subprocess
from socket import *
import struct,json

#1买手机
phone=socket(AF_INET,SOCK_STREAM)

#phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR)
#2绑定银行卡
phone.bind(('127.0.0.1',8081)) #元组内放自己的ip地址
#再次启动服务端,告诉端口已经占用,解决办法有:1.换个端口,8080换掉同时客户端也需要换掉 2.在绑定之前加上下面内容:phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR)
# 防止位置在 #2绑定银行卡 上面

#3开机
phone.listen(5)  #半连接池,5以内接受访问请求。  5是访问数量,也就是说除了正在访问的这个,最多再有5个

#4建立链接的请求
while True:       #需要一个循环不停地与客户端交互
    connect,client=phone.accept()
    print(client)

# 5 收/发消息
    while True:
        try:                           #避免客户端突然中断,不会造成服务端崩溃,针对Windows
            date=connect.recv(1024)    #此处的connect 是 connect,client=phone.accept() 处的,1024是最大的接受字节数
            if len(date)==0:           #针对linux系统的
                break
            cmd=date.decode('utf-8')
            obj=subprocess.Popen(cmd,shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            res1=obj.stdout.read()
            res2=obj.stderr.read()

            head_dic={
                'filename':'a.txt',
                'total_size':len(res1)+len(res2),
                'md5':'12345dvxvvv'
            }
            header_json=json.dumps(head_dic)
            head_bytes=header_json.encode('utf-8')

            #先发4个字节
            connect.send(struct.pack('i',len(head_bytes)))   #字节长度是4个
            #再发报头字典
            connect.send(head_bytes)
            #再发真正的数据
            connect.send(res1)
            connect.send(res2)
        except Exception:
            break
    connect.close()

 

 

 

二:阿里云部署

1.部署步骤

(1)

1.登陆阿里云官网

https://cn.aliyun.com/
2.右上角注册,可以用支付宝扫码登陆
3.点左上角最新活动
4.然后往下拉有个精彩活动,,里面有个阿里云试用中心,点立即查看
5.然后选那个右上角有个人用户字样,可以试用一个月的,就可以试用了,但是好像要先实名注册一下

(2)

注册完就可以拿到一个公网IP地址,可以试用一个月,还有试用的时候,让你选网速,可以调成最大,就是5Mbps,反正都是免费的,还有最重要的一点,自动续费那个选项千万不要勾选

申请完还会给你发个短信,短信里会告诉你怎么设置密码,还会有小姐姐给你打电话,发邮箱,让你有问题联系她,密码是一定要设置的,不然上不去,好像还要设置一下端口

(3)

全部弄好以后,可以照这个网址https://www.cnblogs.com/kimyeee/p/7250560.html装一下python3,然后就可以当服务端用了

 

2.过程中

 

 

 

 

三:udp协议的套接字

特点:没有粘包,只管收发,不稳定,适用于访问和消息发送

服务端:


from socket import *
server=socket(AF_INET,SOCK_DGRAM)
server.bind(('127.0.0.1',9999))

while True:
    date,client_addr=server.recvfrom(1024)
    print(date,client_addr)
    server.sendto(date.upper(),client_addr)

 

客户端:


from socket import *
client=socket(AF_INET,SOCK_DGRAM)


while True:
    msg=input('>>>').strip()
    client.sendto(msg.encode('utf-8'),('127.0.0.1',9999))
    res,sever_adder=client.recvfrom(1024)
    print(res.decode('utf-8'))

 

三:socketsever模块的使用

 

功能在于同时并发几个客户端

服务端:

import socketserver
class MyRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                date=self.request.recv(1024)
                if len(date)==0:
                    break
                print(date)
                self.request.send(date.upper())
            except Exception:
                break
        self.request.close()

server=socketserver.ThreadingTCPServer(('127.0.0.1',8085),MyRequestHandler,bind_and_activate=True)
server.serve_forever()
客户端1:


import socket
#1买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #流式协议

#2打电话
phone.connect(('127.0.0.1',8085))

#3发/收数据
while True:
    msg=input('<<<<').strip()
    if len(msg)==0:                      #避免客户端输入是空的时候出现异常,下面的无法操作
        continue
    phone.send(msg.encode('utf-8'))
    date=phone.recv(1024)
    print(date.decode('utf-8'))

#4关闭
phone.close()

 

客户端2:


import socket
#1买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #流式协议

#2打电话
phone.connect(('127.0.0.1',8085))

#3发/收数据
while True:
    msg=input('<<<<').strip()
    if len(msg)==0:                      #避免客户端输入是空的时候出现异常,下面的无法操作
        continue
    phone.send(msg.encode('utf-8'))
    date=phone.recv(1024)
    print(date.decode('utf-8'))

#4关闭
phone.close()

 

posted @ 2021-01-18 22:27  zz_yy  阅读(234)  评论(0编辑  收藏  举报
/* 鼠标点击求赞文字特效 */