python使用socket实现简易云端字典数据存取

因为实际需求,代码中只传输了整数数据。稍作修改即可传输其他类型数据

数据收发逻辑

建立连接之后,如果发送了不属于已有cid(字典key)的8bit char数据,则为其在1~127分配一个新的cid。如果是已有cid,则继续读取一个8bit char作为命令。w为更新cid对应值,l为列出所有cidr为读取一个cid对应的值。

  • 对于w,传输一个32bit int值即可对相应cid进行更新。特别地,传输0将会删除该cid
  • 对于l,服务器将首先发回一个8bit char代表cid的个数,紧接着依次发送每个cid,即字典的key,每个值均为8bit
  • 对于r,接收一个8bit charcid,返回该cid对应的32bit int值。

错误处理

  • 返回-1:接收数据错误,该cid对应的值将被更新为-1
  • 返回-2:初始字典值
  • 返回-3:获取cid错误
  • 返回-4:获取cmd错误
  • 返回-5:目标cid错误,字典中无该key对应值
  • 返回-6:客户端(cid)数已满

代码实现

服务端

#!/usr/bin/python3
#server
import socket               # 导入 socket 模块
import random

def sendnbyte(c, data, num):
    try:
        c.send(data.to_bytes(num, "little"))
        print("发出数据:", data, "字节数为", num)
    except Exception as e:
        print("发送数据错误!\n", e)

def getint(c):
    try:
        return int.from_bytes(c.recv(4), byteorder = "little")
    except Exception as e:
        print("接收数据错误!\n", e)
        return -1 & 0xffffffff

def getcid(c):
    try:
        return int.from_bytes(c.recv(1), byteorder = "little")
    except Exception as e:
        print("获取cid错误!\n", e)
        return -3 & 0xffffffff

def getcmd(c):
    try:
        return c.recv(1).decode()
    except Exception as e:
        print("获取char错误!\n", e)
        return -4 & 0xffffffff

s = socket.socket()         # 创建 socket 对象
host = "0.0.0.0"	    	# 获取本地ip
port = 12345                # 设置端口
s.bind((host, port))        # 绑定端口

s.listen(127)               # 等待客户端连接
data = {}                   # 客户端数据字典
while True:
    c,addr = s.accept()     # 建立客户端连接
    print("连接地址", addr)
    cid = getcid(c)
    if cid in data:
        print("客户端id是", cid)
        cmd = getcmd(c)
        print("得到命令:", cmd)
        if(cmd == 'w'): #w 119
            data[cid] = getint(c)
            print("写入数据:", data[cid], '@', cid)
            if data[cid] == 0:
                data.pop(cid)
                print("删除cid:", cid)
        elif(cmd == 'l'): #l 108
            print("现有cid:", data.keys())
            sendnbyte(c, len(data), 1)
            for key in data.keys(): sendnbyte(c, key, 1)
        elif(cmd == 'r'): #r 114
            cid = getcid(c)
            if cid in data:
                print('获取', cid, "的值并", end = '', sep = '')
                sendnbyte(c, data[cid], 4)
            else:
                print("目标cid错误!")
                sendnbyte(c, -5 & 0xffffffff, 4)
    else:
        if(len(data) >= 127):
            print("客户端数已满!")
            sendnbyte(c, -6 & 0xffffffff, 1)
            continue
        cid = random.randint(1, 127)
        while cid in data: cid = random.randint(1, 127)
        print("为新客户端分配id:", end = '')
        sendnbyte(c, cid, 1)
        data[cid] = -2 & 0xffffffff
    c.close()                # 关闭连接

客户端

#client
import socket               # 导入 socket 模块

s = socket.socket()         # 创建 socket 对象
host = socket.gethostbyname("localhost") # 获取服务器ip
port = 12345                # 设置端口号
data = 10086                # 欲传送数据
rdata = 0                   # 接收数据变量

print("连接到服务器: ", host, ':', port, sep = '')
s.connect((host, port))
cid = 0
s.send(cid.to_bytes(1, "little"))
cid = int.from_bytes(s.recv(1), byteorder = "little")
print("获得id:", cid)
s.close()

s = socket.socket()
s.connect((host, port))
s.send(cid.to_bytes(1, "little"))
s.send('w'.encode())
data = int(input("请输入欲传输整数数据: "))
s.send(data.to_bytes(4, "little"))
print("传输数据:", data, "对应cid:", cid)
s.close()

s = socket.socket()
s.connect((host, port))
s.send(cid.to_bytes(1, "little"))  # 本机cid
s.send('l'.encode())
leng = int.from_bytes(s.recv(1), byteorder = "little")
cidlist = []
while leng:
    cidlist.append(int.from_bytes(s.recv(1), byteorder = "little"))
    leng = leng - 1
cidlist.sort()
print("现有cid:", cidlist)
s.close()

s = socket.socket()
s.connect((host, port))
s.send(cid.to_bytes(1, "little"))  # 本机cid
s.send('r'.encode())
cid = int(input("请输入欲链接cid: "))
while cid not in cidlist:
    cid = int(input("输入id不在列表中!\n请输入欲链接cid: "))
s.send(cid.to_bytes(1, "little"))  # 欲链接cid
rdata = int.from_bytes(s.recv(4), byteorder = "little")
print("接受数据:", rdata, "对应cid:", cid)
s.close()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值