首页 > 编程语言 >【NVIDIA JETSON AGX XAVIER】与个人笔记本(win11)建立TCP-IP连接相互传输数据(含源码)

【NVIDIA JETSON AGX XAVIER】与个人笔记本(win11)建立TCP-IP连接相互传输数据(含源码)

时间:2024-03-16 12:00:03浏览次数:19  
标签:socket IP send client 传输数据 源码 file data conn

文章目录


前言

我的上一篇博客:【NVIDIA JETSON AGX XAVIER】与个人笔记本(win11)建立TCP-IP连接传输数据(含源码)
博客中的代码只能实现从服务器端(个人笔记本(win11))传输数据到客户端(NVIDIA JETSON AGX XAVIER),且只能传输一次文件
本博客将进行优化,并实现双向传输数据。

一、个人笔记本(win11)传输数据到XAVIER(多次传输)

在前面代码的基础上添加循环机制,假如现在服务器ip地址是192.168.0.1

1.服务器端代码(个人笔记本win11)

代码如下(示例):

import socket
import os

def send_file(filename, conn):
    if os.path.isfile(filename):
        # 发送文件存在确认消息
        conn.send(b'EXISTS ' + str(os.path.getsize(filename)).encode())
        user_response = conn.recv(1024).decode()
        if user_response[:2] == 'OK':
            with open(filename, 'rb') as f:
                bytes_to_send = f.read(1024)
                conn.send(bytes_to_send)
                while bytes_to_send:
                    bytes_to_send = f.read(1024)
                    conn.send(bytes_to_send)
    else:
        conn.send(b'ERR ')

def server_program():
    host = socket.gethostname()
    port = 5005
    server_socket = socket.socket()
    server_socket.bind((host, port))
    server_socket.listen(5)
    print("服务器启动,等待连接...")
    conn, address = server_socket.accept()
    print("连接来自: " + str(address))
    while True:
        data = conn.recv(1024).decode()
        if not data:
            # 如果没有接收到数据,继续等待新的文件请求
            continue
        send_file(data, conn)
    conn.close()

if __name__ == '__main__':
    server_program()

2.客户端代码(NVIDIA JETSON AGX XAVIER)

代码如下(示例):

import socket

def client_program():
    host = socket.gethostname()
    port = 5001

    client_socket = socket.socket()
    client_socket.connect(("192.168.0.1", port))
    print("连接成功")

    while True:  # 添加外部循环以持续请求文件
        file_name = input("输入要传输的文件名或输入'exit'退出: ")
        if file_name.lower() == 'exit':
            break
        client_socket.send(file_name.encode())

        data = client_socket.recv(1024).decode()
        if data[:6] == 'EXISTS':
            file_size = int(data[6:])
            client_socket.send(b'OK')
            f = open('new_' + file_name, 'wb')
            data = client_socket.recv(1024)
            total_recv = len(data)
            f.write(data)
            while total_recv < file_size:
                data = client_socket.recv(1024)
                total_recv += len(data)
                f.write(data)
                print("{0:.2f}".format((total_recv/float(file_size))*100)+ "% Done")
            print("下载完成!")
            f.close()
        else:
            print("文件不存在!")

    client_socket.close()

if __name__ == '__main__':
    client_program()

二、两端相互传输(以另一种形式解决上一篇博客的问题)

假如现在服务器ip地址是192.168.0.1

1.服务器端代码(个人笔记本win11)

在前面代码的基础上添加receive_file函数,处理接收的客户端的数据。
代码如下(示例):

import socket
import os

def send_file(filename, conn):
    if os.path.isfile(filename):
        # 发送文件存在确认消息
        conn.send(b'EXISTS ' + str(os.path.getsize(filename)).encode())
        user_response = conn.recv(1024).decode()
        if user_response[:2] == 'OK':
            with open(filename, 'rb') as f:
                bytes_to_send = f.read(1024)
                conn.send(bytes_to_send)
                # while bytes_to_send != "":
                while bytes_to_send:
                    bytes_to_send = f.read(1024)
                    conn.send(bytes_to_send)
    else:
        conn.send(b'ERR ')

def server_program():
    # 获取主机名
    host = socket.gethostname()
    port = 5011  # 初始化端口号
    server_socket = socket.socket()  # 获取socket对象
    server_socket.bind((host, port))  # 绑定地址到socket
    server_socket.listen(5)  # 监听连接,最多可接受5个连接
    print("服务器启动,等待连接...")
    conn, address = server_socket.accept()  # 接受新连接
    print("连接来自: " + str(address))
    while True:
        data = conn.recv(1024).decode()
        if data.startswith('send'):
            filename = data[5:]
            receive_file(filename, conn)
        else:
            send_file(data, conn)
        if not data:
            # break
            continue

    conn.close()  # 关闭连接

def receive_file(filename, conn):
    conn.send(b'READY')
    with open(filename, 'wb') as f:
        while True:
            bytes_read = conn.recv(1024)
            if not bytes_read:
                break
            f.write(bytes_read)


if __name__ == '__main__':
    server_program()

2.客户端代码(NVIDIA JETSON AGX XAVIER)

在前面代码的基础上添加send_file_to_server函数,判断发送给服务器的文件是否存在,修改主函数(client_program),添加"输入 ‘get’ 请求文件,或者 ‘send’ 发送文件,或输入’exit’退出三种模式选择,客户端(Xavier)可以选择收或发文件。
代码如下(示例):

import socket
import os
def client_program():
    host = socket.gethostname()
    port = 5011

    client_socket = socket.socket()
    client_socket.connect(("192.168.0.1", port))
    print("连接成功")

    while True:  # 添加外部循环以持续请求文件
        action = input("输入 'get' 请求文件,或者 'send' 发送文件,或输入'exit'退出:")
        if action.lower() == 'exit':
            break
        elif action.lower() == 'get':
            file_name = input("输入要传输的文件名: ")
            client_socket.send(file_name.encode())
            data = client_socket.recv(1024).decode()
            if data[:6] == 'EXISTS':
                file_size = int(data[6:])
                client_socket.send(b'OK')
                # f = open(r'' + file_name, 'wb')
                f = open(r'new_' + file_name, 'wb')
                data = client_socket.recv(1024)
                total_recv = len(data)
                f.write(data)
                while total_recv < file_size:
                    data = client_socket.recv(1024)
                    total_recv += len(data)
                    f.write(data)
                    print("{0:.2f}".format((total_recv/float(file_size))*100)+ "% Done")
                print("下载完成!")
                f.close()
            else:
                print("文件不存在!")
                client_socket.send(file_name.encode())
        elif action.lower() == 'send':
            file_name = input("输入要发送的文件名: ")
            if os.path.isfile(file_name):  # 在这里添加检查
                send_file_to_server(file_name, client_socket)
                print("成功发送:" + file_name)
            else:
                print("文件不存在,请检查文件名是否正确。")
    client_socket.close()
def send_file_to_server(filename, client_socket):
    if os.path.isfile(filename):  # 检查文件是否存在
        client_socket.send(('send ' + filename).encode())
        response = client_socket.recv(1024).decode()
        if response == 'READY':
            with open(filename, 'rb') as f:
                bytes_to_send = f.read(1024)
                while bytes_to_send:
                    client_socket.send(bytes_to_send)
                    bytes_to_send = f.read(1024)
    else:
        print("文件不存在,请检查文件名是否正确。")
if __name__ == '__main__':
    client_program()

三、传输数据中的缓存问题

运行上述程序出现的问题:客户端在选择进行两次send发送文件时,前一次send发送成功,且能够在服务器上看到传输的文件,但是文件大小为0,过一段时间后,文件才会恢复原本的大小

且再一次的send,输入文件名回车后,程序将没有反应。

在这里插入图片描述

在这里插入图片描述
程序将没有反应。只能直接结束程序,报错如下:
在这里插入图片描述

1.查找资料,发现问题

问题可能与文件传输的同步性有关。当文件内容在传输后为空,但过一段时间后恢复,这可能意味着文件数据在传输过程中被缓存或延迟了。这种情况可能是由于网络延迟或者客户端和服务器之间的同步问题。

对于客户端在第一次发送文件后无法再次发送文件的问题,这可能是因为客户端或服务器的socket没有正确地处理连续的send操作。在某些情况下,如果发送缓冲区没有被及时清空,或者前一次的数据还没有完全发送完毕,再次尝试send可能会失败。

2.尝试解决

以下是一些可能的解决方法:

  1. 确认发送和接收程序的同步:确保发送方在发送完一个文件后,接收方已经完全接收并处理了该文件。可以通过在发送方和接收方之间实现一个简单的确认机制,例如发送方在发送完一个文件后等待接收方的确认消息,然后再进行下一个文件的发送。

  2. 检查网络状况:网络延迟或不稳定可能会导致文件传输中断或延迟。确保网络连接稳定,并考虑使用更可靠的网络连接。

  3. 使用流控制协议:如果您正在使用自定义的文件传输协议,考虑实现TCP-like的流控制机制,如滑动窗口协议,以确保数据的可靠传输。

  4. 调整socket选项:在某些情况下,调整socket的行为可以帮助解决问题。例如,设置socket为非阻塞模式,并使用select或epoll来监控socket的状态,这样可以更有效地管理发送缓冲区和避免发送阻塞。

  5. 使用现有的文件传输协议:如果可能,考虑使用现有的文件传输协议,如FTP或SFTP,这些协议提供了更完善的错误检查和恢复机制,适合传输大文件。

  6. 检查程序逻辑:仔细检查客户端和服务器程序的逻辑,确保在发送和接收文件时,程序能够正确处理连续的send操作。

尝试上述方法并未解决!判断可能是网络延迟问题


总结

本博客建立了 XAVIER与个人笔记本(win11)的TCP-IP连接并实现了相互传输数据,但传输过程中存在缓存问题,不能保证每次传输都能够成功,还需要优化程序!

标签:socket,IP,send,client,传输数据,源码,file,data,conn
From: https://blog.csdn.net/m0_62640704/article/details/136744363

相关文章

  • Eclipse程序安装包下载
    程序安装包下载程序1:EclipseIDEforEnterpriseJavaandWebDevelopers这个软件是免费的,可以从下面的链接自行下载:https://www.eclipse.org/downloads/packages/release/2022-12/r/eclipse-ide-enterprise-java-and-web-developers程序2:MySQL-win64打开手机微信App,扫码推......
  • 如果本电脑中无pip指令,则可以按下面方法即可安装pip及运行它
    第一步:点击下面网址:https://pypi.org/project/pip/#files该网址下载tar文件,并解压到一个磁盘里Win+R键打开cmd,cd到解压磁盘的目录,运行命令:python setup.py install第二步:我Python安装的目录是:C:\Users\天天开心那是必须滴\AppData\Local\Programs\Python\Python39\S......
  • GDCM:实现读取DICOM属性并打印(附完整源码)
    GDCM:实现读取DICOM属性并打印下面是一个使用GDCM库读取DICOM文件属性并打印它们的示例代码:#include<iostream>#include"gdcmReader.h"#include"gdcmFile.h"#include"gdcmDataSet.h"#include"gdcmAttribute.h"intmain(intargc,char*argv[])......
  • PIP 脚本
    @echooffsetPYTHONIOENCODING=utf-8setPYPI_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simplerem使用pip安装ugotpipinstallugot-i%PYPI_MIRROR%rem使用pip安装requestspipinstallrequests-i%PYPI_MIRROR%pipinstallconcurrent-log-handler-i%PYPI_MIRR......
  • java毕设安卓基于安卓的图库管理系统(开题+源码)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着移动互联网技术的快速发展和智能手机普及率的不断攀升,人们对于移动设备上信息管理和共享的需求日益增长。安卓作为目前全球最受欢迎的移动操作系......
  • java毕设安卓基于安卓的汽车租赁系统的设计与实现(开题+源码)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着科技的飞速发展,移动互联网已经渗透到我们生活的方方面面,其中,移动应用在汽车租赁行业中扮演着日益重要的角色。近年来,汽车租赁市场呈现出蓬勃的发......
  • Spring 5.x 源码之旅-59AOP事务的初始化流程一
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • Spring 5.x 源码之旅-59AOP事务的初始化流程二
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • 直播软件源码,异常偶有发生我们该如何处理?
    直播软件源码,异常偶有发生我们该如何处理?初识异常异常与异常处理:异常既错误异常会导致程序崩溃并停止运行异常处理可以捕获到异常,将异常部位的程序进行处理使得直播软件源码继续正常运行异常处理的结构由try-except代码块组成try:代码块#被try关键字......
  • 直播带货源码,异步处理中会处理两次请求
    直播带货源码,异步处理中会处理两次请求从序列图上可以看到SpringMVC在处理异步请求时,DispatcherServlet会处理两次请求具体来看HandlerAdapter的处理过程//根据HandlerMethod解析参数并完成过程调用得到一个ModelAndViewprivateModelAndViewinvokeHandleMethod(Ht......