framing

本文探讨了网络通信中消息帧定界的重要性和实现方法,包括如何确保接收方正确识别消息边界并完整接收数据。通过Python示例代码展示了服务器端与客户端如何利用close()和recv()来完成这一过程。

framing:
如何分割消息,使得接收方能够识别消息的开始,由于传递给sendall()的数据可能在实际网络传输的时候被分割成多个数据包,接收消息的程序可能需要进行多个recv()调用才能读取完整的消息。

关于framing需要考虑这样的问题:
接收方合适最终停止调用recv()才是安全的,整个消息或数据合适才能完整无缺的传达?合适才能将接收到的信息作为一个整体来解析或处理?

模式一,
发送方循环不断的发送数据,知道所有的数据都被传递给sendall()为止,然后使用close()关闭套接字,接收方只需要不断地调用recv(),直到recv()最后返回一个空格字符为止。

#!/usr/bin/env python3
#-*- encoding:utf8 -*-

import socket
from argparse import ArgumentParser

def server(address):
    sock = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET , socket.SO_REUSEADDR , 1)
    sock.bind(address)
    sock.listen(1)

    print('Run this script in another window with "-c" to connect')
    print('listening at' , sock.getsockname())

    sc,sockname = sock.accept()
    print('Accepted connection from ' , sockname)
    sc.shutdown(socket.SHUT_WR)

    message = b''
    while True:
        more = sc.recv(8192)
        if not more:
            print('Receive None!')
            break
        print('Receive {} Bytes'.format(len(more)))
        message += more
    print('Message:\n')
    print(message.decode())
    sc.close()
    sock.close()


def client(address):
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.connect(address)
    sock.shutdown(socket.SHUT_RD)
    sock.sendall(b'Beautiful is better than ugly.\n')
    sock.sendall(b'Explicit is better than implicit.\n')
    sock.sendall(b'Simple is better than complex.\n')
    sock.close()

if __name__ == "__main__":
    parser = ArgumentParser(description='Transmit and receive a data stream')
    parser.add_argument('hostname' , nargs='?' , default='127.0.0.1',
                        help='IP or hostname (default:%(default)s)')
    parser.add_argument('-c' , action='store_true' , help='run as the client')
    parser.add_argument('-p' , type=int , metavar = 'port' , default = 1060 ,
                        help='TCP port number (default:%(default)s)')
    args = parser.parse_args()
    function = client if args.c else server
    function((args.hostname , args.p))

 

转载于:https://www.cnblogs.com/alben-cisco/p/7083044.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值