• 网络编程(二)


    一.socket(套接字)

    1.基于TCP协议的socket通信  

    sever端

     1 import socket
     2 sk = socket.socket()
     3 sk.bind(('127.0.0.1',8898))  #把地址绑定到套接字
     4 sk.listen()          #监听链接
     5 conn,addr = sk.accept() #接受客户端链接
     6 ret = conn.recv(1024)  #接收客户端信息
     7 print(ret)       #打印客户端信息
     8 conn.send(b'hi')        #向客户端发送信息
     9 conn.close()       #关闭客户端套接字
    10 sk.close()        #关闭服务器套接字(可选)

    client端

    import socket
    sk = socket.socket()           # 创建客户套接字
    sk.connect(('127.0.0.1',8898))    # 尝试连接服务器
    sk.send(b'hello!')
    ret = sk.recv(1024)         # 对话(发送/接收)
    print(ret)
    sk.close()            # 关闭客户套接字

    2.标准通信循环

    server端

    import socket
    server = socket.socket()  # 生成一个对象
    server.bind(('127.0.0.1',8080))  # 绑定ip和port
    server.listen()  # 半连接池
    
    while True:
        conn, addr = server.accept()  
        print(addr)  # ('127.0.0.1', 51323) 客户端的地址
        while True:
            try:
                data = conn.recv(1024)
                print(data) 
                if len(data) == 0:break
                conn.send(data.upper())
            except ConnectionResetError as e:
                print(e)
                break
        conn.close()

    client端

    import socket
    
    client = socket.socket()
    client.connect(('127.0.0.1',8080))
    
    while True:
        msg = input('>>>:').encode('utf-8')
        if len(msg) == 0:continue
        client.send(msg)
        data = client.recv(1024)
        print(data)

    3.粘包问题

    server端

    import socket
    import subprocess
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    
    while True:
        conn,addr = sk.accept()
        while True:
            try:
                cmd = conn.recv(1024).decode('utf-8')
                if len(cmd) == 0:break
                res = subprocess.Popen(cmd,shell= True,
                                       stderr=subprocess.PIPE,
                                       stdout=subprocess.PIPE)
                stdout = res.stdout.read()
                stderr = res.stderr.read()
                conn.send(stdout)
                conn.send(stderr)
            except ConnectionResetError:
                break

    client端

    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    
    while True:
        cmd = input('请输入cmd:').strip()
        if len(cmd) == 0 :continue
        sk.send(cmd.encode('utf-8'))
        res = sk.recv(1024)
        print(res.decode('gbk'))

    粘包造成的原因:

    粘包现象只发生在tcp协议中:

    1.从表面看,粘包问题主要是因为发送方和接收方的缓存机制,tcp协议面向流通信的特点

    2.实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

    4.解决粘包

    server端

    import socket
    import subprocess
    import json
    import struct
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    
    while True:
        conn,addr = sk.accept()
        while True:
            try:
                cmd = conn.recv(1024).decode('utf-8')
                if len(cmd) == 0:break
                res = subprocess.Popen(cmd,shell= True,
                                       stderr=subprocess.PIPE,
                                       stdout=subprocess.PIPE)
                stdout = res.stdout.read()
                stderr = res.stderr.read()
                ret = stdout+stderr
                head = {'name':'zzp','size':len(ret)}
                json_head = json.dumps(head)
                head_pack = struct.pack('i',len(json_head))
                sk.send(head_pack)
                sk.send(json_head.encode('utf-8'))
                sk.send(ret)
            except ConnectionResetError:
                break

    client端

    import socket
    import struct
    import json
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    
    while True:
        cmd = input('请输入cmd:').strip()
        if len(cmd) == 0 :continue
        sk.send(cmd.encode('utf-8'))
        head_pack = sk.recv(4)
        head_len = struct.unpack('i',head_pack)[0]
        head_json = sk.recv(head_len).decode('utf-8')
        head = json.loads(head_json)
        size = head['size']
        recv_size = 0
        real_data = b''
        while recv_size < size:
            data = sk.recv(1024)
            real_data += data
            recv_size += len(data)
        print(real_data.decode('gbk'))
    万般皆下品,唯有读书高!
  • 相关阅读:
    Educational Codeforces Round 61
    Codeforces Round #548 (Div. 2)
    Codeforces Round #553 (Div. 2)
    spring mvc接口跨域访问
    json解析;百度统计API返回data解析
    HTML img标签使用base64展示图片
    My Sql 查询连续天数数据
    js 获取url地址栏拼接参数
    在jsp页面获取绝对路径
    java web项目配置Tomcat访问项目外文件
  • 原文地址:https://www.cnblogs.com/s686zhou/p/11316000.html
Copyright © 2020-2023  润新知