You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于COT协议,能否通过XML在TCP套接字传输图片与文件?

关于COT协议中通过XML直接在TCP套接字传输文件的问题

当前使用场景

我目前在使用COT协议,当前通过URL方式在XML消息中传输文件,代码示例如下:

import datetime
import uuid
import xml.etree.ElementTree as ET
# 假设以下常量已定义:DATETIME_FORMAT, STALE_DURATION, ATTITUDE, DIMENSION, HOW, CALLSIGN, PACKAGE_FILE_NAME, SERVER_IP, SERVER_PORT, SENDER_CALLSIGN, SENDER_UID, FILESHARE_NAME

def composeMessage(uid, lat, lon, file_path=None):
    # Initialize CoT parameters
    now = datetime.datetime.utcnow()
    start = now.strftime(DATETIME_FORMAT)
    time = now.strftime(DATETIME_FORMAT)
    stale = (now + datetime.timedelta(minutes=STALE_DURATION)).strftime(DATETIME_FORMAT)
    if file_path:
        size = str(calcSize(file_path))
        hash = str(calcHash(file_path))

    # Build XML
    event = ET.Element('event')
    event.set('version', '2.0')
    event.set('uid', uid)
    event.set('type', f"a-{ATTITUDE}-{DIMENSION}")
    event.set('how', HOW)
    event.set('start', start)
    event.set('time', time)
    event.set('stale', stale)

    detail = ET.SubElement(event, 'detail')
    contact = ET.SubElement(detail, 'contact')
    contact.set('callsign', CALLSIGN)
    remarks = ET.SubElement(detail, 'remarks')

    if file_path:
        fileshare = ET.SubElement(detail, 'fileshare')
        fileshare.set('filename', PACKAGE_FILE_NAME)
        url = f'http://{SERVER_IP}:{SERVER_PORT}/getfile?file={uid}&sender={SENDER_CALLSIGN}'
        # how can I turn it into url a file? 
        fileshare.set('senderUrl', url) 
        fileshare.set('sizeInBytes', size)
        fileshare.set('sha256', hash)
        fileshare.set('senderUid', SENDER_UID)
        fileshare.set('senderCallsign', SENDER_CALLSIGN)
        fileshare.set('name', FILESHARE_NAME)

        ackreq = ET.SubElement(detail, 'ackrequest')
        ackreq.set('uid', uuid.uuid4().hex)
        ackreq.set('ackrequested', 'true')
        ackreq.set('tag', PACKAGE_FILE_NAME)

    point = ET.SubElement(event, 'point')
    point.set('le', '0.0')
    point.set('ce', '1.0')
    point.set('hae', '10.0')
    point.set('lat', str(lat))
    point.set('lon', str(lon))

    return ET.tostring(event)

问题咨询

我了解到图片和数据可通过XML传输,想咨询是否可以直接通过XML在TCP套接字连接中传输文件?


回答

可以直接通过XML在TCP套接字连接中传输文件,但需要对文件内容做Base64编码处理,具体说明如下:

核心原理

XML是纯文本格式,无法直接存储二进制文件内容。Base64编码能将二进制数据转换为ASCII字符串,使其可以合法嵌入到XML的元素文本或属性中,从而通过TCP套接字传输整个XML消息。

实现步骤

  1. 编码文件内容:读取文件的二进制数据,用Base64编码为UTF-8字符串
  2. 嵌入XML结构:在<fileshare>节点下新增一个子元素(如<content>),将编码后的字符串写入该元素的文本内容
  3. 接收方解码:解析XML消息时提取<content>的文本,解码回二进制数据后写入本地文件

修改后的代码示例

import datetime
import uuid
import xml.etree.ElementTree as ET
import base64  # 新增Base64模块引用

# 假设以下常量已定义:DATETIME_FORMAT, STALE_DURATION, ATTITUDE, DIMENSION, HOW, CALLSIGN, PACKAGE_FILE_NAME, SERVER_IP, SERVER_PORT, SENDER_CALLSIGN, SENDER_UID, FILESHARE_NAME

def composeMessage(uid, lat, lon, file_path=None):
    # Initialize CoT parameters
    now = datetime.datetime.utcnow()
    start = now.strftime(DATETIME_FORMAT)
    time = now.strftime(DATETIME_FORMAT)
    stale = (now + datetime.timedelta(minutes=STALE_DURATION)).strftime(DATETIME_FORMAT)
    file_content = None
    if file_path:
        size = str(calcSize(file_path))
        hash = str(calcHash(file_path))
        # 读取文件并Base64编码
        with open(file_path, 'rb') as f:
            file_content = base64.b64encode(f.read()).decode('utf-8')

    # Build XML
    event = ET.Element('event')
    event.set('version', '2.0')
    event.set('uid', uid)
    event.set('type', f"a-{ATTITUDE}-{DIMENSION}")
    event.set('how', HOW)
    event.set('start', start)
    event.set('time', time)
    event.set('stale', stale)

    detail = ET.SubElement(event, 'detail')
    contact = ET.SubElement(detail, 'contact')
    contact.set('callsign', CALLSIGN)
    remarks = ET.SubElement(detail, 'remarks')

    if file_path:
        fileshare = ET.SubElement(detail, 'fileshare')
        fileshare.set('filename', PACKAGE_FILE_NAME)
        # 移除senderUrl,添加Base64编码的内容节点
        content_elem = ET.SubElement(fileshare, 'content')
        content_elem.text = file_content
        fileshare.set('sizeInBytes', size)
        fileshare.set('sha256', hash)
        fileshare.set('senderUid', SENDER_UID)
        fileshare.set('senderCallsign', SENDER_CALLSIGN)
        fileshare.set('name', FILESHARE_NAME)

        ackreq = ET.SubElement(detail, 'ackrequest')
        ackreq.set('uid', uuid.uuid4().hex)
        ackreq.set('ackrequested', 'true')
        ackreq.set('tag', PACKAGE_FILE_NAME)

    point = ET.SubElement(event, 'point')
    point.set('le', '0.0')
    point.set('ce', '1.0')
    point.set('hae', '10.0')
    point.set('lat', str(lat))
    point.set('lon', str(lon))

    return ET.tostring(event)

注意事项

  • 数据体积膨胀:Base64编码会让原始数据体积增加约33%,大文件(如几百MB以上)会导致XML消息过大,可能引发TCP传输延迟、丢包或内存溢出问题,仅推荐用于小文件传输
  • 解析兼容性:确保接收方的XML解析器能处理大文本节点,避免因内存不足导致解析失败
  • 元数据保留:仍需保留文件名、大小、哈希值等元数据,方便接收方验证文件完整性和正确命名

内容的提问来源于stack exchange,提问作者nogabemist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:21:31