ftl1012

原则:发送一个接受一个

原理:发送执行命令的大小给客户端,客户端根据接受的大小判断是否全部接收了服务器sendall()发送的全部

利用send发送的全部数据都是bytes类型的,需要进行字符编码的转换,因为中文环境,所以需要转换GBK查看

客户端:

# 客户端
import socket

# family=AF_INET,   代表使用IPV4的IP协议
# type=SOCK_STREAM  代表使用TCP协议进行连接
client = socket.socket()
ip_addr = (\'127.0.0.1\', 9999)
try:
    client.connect(ip_addr)
    exit_flag = True
    while exit_flag:
        # 发送一定要有接收
        inp = input(\'>>>:\')
        if inp != \'bye\':
            client.send(bytes(inp, \'utf-8\'))
            exit_flag = True
        else:
            client.send(bytes(inp, \'utf-8\'))
            exit_flag = False
        result_len = int(str(client.recv(1024), encoding=\'utf-8\')) # 接受服务器端发送的数据大小
        print(\'客户端接收的大小为:\', result_len)
        data_size = bytes()
        while len(data_size) != result_len:
            info = client.recv(1024)    # 最大接收1024K数据,# 传送/接收的数据一定是byte类型
            data_size += info
        print(\'客户端:\', str(data_size, \'gbk\')) # Win7系统就是GBK编码返回的数据
except Exception as e:
    print(\'客户端关闭连接\', e)
finally:
    client.close()

服务端:

# 服务端
import socket
import subprocess
# family=AF_INET,   代表使用IPV4的IP协议
# type=SOCK_STREAM  代表使用TCP协议进行连接
server = socket.socket()  # 创建socket
ip_addr = (\'127.0.0.1\', 9999)  # 1024之前的端口,默认是OS使用
server.bind(ip_addr)           # 要求必须是一个元组
server.listen(3)               # 开始监听传入连接。在拒绝连接之前,可以挂起的最大连接数量。
while True:
    conn, addr = server.accept() # 接受连接并返回(conn,address)
                                 # 其中conn是新的套接字对象[客户端],可以用来接收和发送数据。
                                 # address是连接客户端的地址。
    exit_flag = True
    while exit_flag:
        print(\'当前连接对象\', addr)
        # 发送一定要有接收
        data = conn.recv(1024)
        print(\'服务器:\', str(data, \'utf-8\'))
        obj = subprocess.Popen(str(data, \'utf-8\'), shell=True, stdout=subprocess.PIPE)
        cmd_result = obj.stdout.read()  # 编码用GBK,默认在当前文件所在的文件路径
        conn.sendall(bytes(str(len(cmd_result)), encoding=\'utf-8\'))   # 发送数据大小,int不能直接转换为bytes
        print(\'服务器发送的大小为:\', len(cmd_result))  # 某种程度上解决了粘包现象
        conn.sendall(cmd_result)        # 发送全部的数据
server.close()

 

注意:  粘包现象: 在服务器端连续send()的时候,2个send直接会等待很短的时间,所以导致传递过去的len会报错,因为不能转换为int型,可以利用Time.sleep解决,也可以遵循一收一发的原则,发送一个以后在发送一次解决。

分类:

技术点:

相关文章:

  • 2021-11-22
  • 2021-12-21
  • 2021-11-06
  • 2021-12-23
  • 2021-08-25
  • 2021-12-29
  • 2021-10-19
  • 2021-11-22
猜你喜欢
  • 2022-01-02
  • 2021-12-23
  • 2022-01-02
  • 2022-01-02
  • 2021-12-23
  • 2021-12-23
  • 2021-12-23
相关资源
相似解决方案