TCP通信的文件上传案例

原理:客户端读取本地的文件,把文件上传到服务器,服务器在把上传的文件保存到服务器的硬盘上

1、客户端使用【本地的字节输入流】,读取要上传的文件
2、客户端使用【网络字节输出流】,把读取到的文件上传到服务器
3、服务器使用【网络字节输出流】,读取客户端上传的文件
4、服务器使用【本地的字节输出流】,把读取到的文件,保存到服务器的硬盘上
5、服务器使用【网络字节输出流】,给客户端回写一个“上传成功”
6、客户端使用【网络字节输入流】,读取服务器回写的数据
7、释放资源

注意:
1、客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流对象(本地流)
2、客户端和服务器之间进行读写,必须使用Socket中提供的字节流对象(网络流)

文件上传的原理
* 就是文件的复制
* 明确:数据源 、 数据目的地

具体代码如下:

/* 服务端 代码*/
public class TCPServer {

    public static void main(String[] args) {

        String filePath = TCPClient.class.getResource("").getPath();
        Socket socket = null;
        FileOutputStream fos = null;

        try {
            // 解决路径中含有空格的情况
            filePath = filePath.replaceAll("%20","");
            // 1、创建一个服务器 ServerSocket 对象,和系统要指定的端口号
            ServerSocket server = new ServerSocket(9999);
            // 2、使用 ServerSocket对象中的方法 accept,获取到请求的客户端 Socket 对象
            socket = server.accept();
            // 3、使用 Socket 对象中的方法 getInputStream,获取到网络字节输入流对象
            InputStream inputStream = socket.getInputStream();

            // 4、判断 文件是否存在,不存在则创建
            File file = new File(filePath);
            if (!file.exists()){
                file.mkdirs();
            }

            // 自定义文件名
            String fileName = System.currentTimeMillis()+ new Random().nextInt(999999)+".text";
            // 5、创建一个本地字节输出流 FileOutputStream 对象,构造方法中绑定要输出的目的地
            fos = new FileOutputStream(file+"/"+fileName);


            int len = 0;
            byte[] bytes = new byte[1024];
            // 6、使用网络字节输入流 InputStream 对象中的方法 read ,读取客户端上传的文件
            while((len = inputStream.read(bytes)) != -1) {
                // 7、使用本地字节输出流 FileOutputStream 对象中的方法 write,把读取到的文件保存到服务器的硬盘中
                fos.write(bytes,0,len);
            }

            /*
             注意上面这个 while 循环的地方
              * 由于上面 while 循环,判断 是否读取到文件结束标记。 但实际上这边的 read 方法是读取不到这个结束标记的,
                因为客户端就没有将这个结束标记告诉服务端
              * api 给出的解释:从此输入流中将最多 bytes.length 个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。
                由此可见 这边的read 方法是被阻塞了
              * 解决办法使 在客户端给出 结束标志
            */


            // 8、使用 Socket 对象中的方法 getOutputStream,获取到网络字节输出流 OutputStream 对象
            // 9、使用网络字节输出流OutputStream对象中的方法 write,给客户端回写"上传成功"
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write("文件保存成功".getBytes());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            // 10、释放资源(FileOutputStream,Socket,Server)
            if(socket != null && fos != null) {
                try {
                    socket.close();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}
/* 客户端 代码*/
public class TCPClient {

    public static void main(String[] args) {

        // String filePath = TCPClient.class.getResource("技术AB题库(更新至3.11号).docx").getPath();
        String filePath = TCPClient.class.getResource("acitviti.txt").getPath();
        FileInputStream fis = null;
        Socket socket = null;

        try {
            // 解决路径中含有空格的情况
            filePath = filePath.replaceAll("%20","");
            // 解决路径包含中文的情况
            filePath = java.net.URLDecoder.decode(filePath,"utf-8");
            // 1、创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
            fis = new FileInputStream(filePath);
            // 2、创建一个客户端 Socket 对象,构造方法中绑定服务器的IP地址和端口
            socket = new Socket(InetAddress.getByName("localhost").getHostAddress(),9999);
            // 3、使用 Socket 中的方法 getOutputStream,获取网络字节输出流 OutputStream 对象
            OutputStream outputStream = socket.getOutputStream();
            // 4、使用本地字节输入流FileInputStream对象中的方法read,读取本地文件

            // 读取本地的流是一个重复的过程
            int len = 0;
            byte[] bytes = new byte[1024];// 提高效率
//            System.out.println((len = fis.read(bytes)));
            while((len = fis.read(bytes))!= -1){
                // 5、使用网络字节输出流 OutputStream 对象中的方法 write ,把读取到的文件上传到服务器
                outputStream.write(bytes,0,len);

            }


            // 给出读取结束标志
            socket.shutdownOutput();


            // 6、使用 Socket 中的方法 getInputStream,获取网络字节输入流 InputStream对象
            InputStream inputStream = socket.getInputStream();

            // 7、使用网络字节输入流 InputStream 对象中的方法read 读取服务器回写的数据
            while((len = inputStream.read(bytes))!= -1){
                System.out.println(new String(bytes,0,len));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            // 8、释放资源(FileInputStream,Socket)
            if(fis != null && socket !=null){
                try {
                    fis.close();
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}

上面服务端的代码,还优化成 多线程 ,这样效率会更高,就是将处理上传文件的逻辑代码放到 run 方法里面执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: LWIP(Lightweight IP)是一个轻量级的、能实现TCP/IP协议栈的开源软件库。而TFTP(Trivial File Transfer Protocol)是一种简单的文件输协议。 使用LWIP库提供的函数,可以通过TFTP协议上文件。首先,需要创建一个TFTP客户端,并设置服务器的IP地址和端口号。然后,指定上文件名和文件的位置。可以使用lwip_tftp_put()函数来实现上。 在上过程中,TFTP客户端将文件分割成多个数据包,并通过TFTP协议发送给服务器。服务器接收到数据包后,会进行校验,并发送确认消息回复给客户端。客户端根据服务器的回复继续发送下一个数据包,直到文件完成。 在上完成后,服务器会发送一个最终确认消息给客户端,表示文件成功。客户端可以根据这个确认消息做进一步的处理,例如关闭TFTP客户端连接。 总而言之,使用LWIP库提供的TFTP客户端函数,可以方便地实现文件功能。通过指定服务器的IP地址和端口号,以及上文件名和位置,即可将文件通过TFTP协议上到服务器。 ### 回答2: lwIP是一个轻量级的TCP/IP协议栈,提供了用于嵌入式系统的网络通信功能。其中包括了使用TFTP(Trivial File Transfer Protocol,简单文件输协议)上文件的功能。 在lwIP中,使用TFTP上文件可以通过以下步骤完成: 1. 初始化lwIP协议栈:首先需要初始化lwIP协议栈,包括网络接口、IP地址等信息的配置。 2. 创建TFTP客户端:接下来,需要创建一个TFTP客户端实例,用于进行文件输。 3. 配置TFTP服务器信息:在TFTP客户端中,需要配置TFTP服务器的IP地址和端口号,以及上文件的目标路径。 4. 打开本地文件:在进行文件之前,需要打开本地的待上文件,并进行读取准备。 5. 启动TFTP上:当上述准备工作完成后,可以调用TFTP客户端的上函数,将本地文件到TFTP服务器。 6. 监听上状态:在上过程中,可以通过回调函数获取上状态的通知,包括输进度、错误信息等。 7. 关闭TFTP客户端和本地文件:上完成后,需要关闭TFTP客户端和本地文件的句柄,释放相关资源。 通过以上步骤,就可以使用lwIP中的TFTP功能进行文件。需要注意的是,具体的实现可能会根据不同的嵌入式系统和应用场景而有所差异,因此在使用时需要参考lwIP和TFTP相关的文档和示例代码进行配置和开发。 ### 回答3: lwIP是一个轻量级的开源TCP/IP协议栈,支持多种网络连接,包括以太网、Wi-Fi和PPP等。TFTP(Trivial File Transfer Protocol)是一种简单的文件输协议,常用于嵌入式系统中对设备进行固件升级或配置文件输。 在lwIP中使用TFTP协议上文件可以通过以下步骤实现: 1. 配置lwIP的TFTP选项:在lwIP的配置文件中,需要开启TFTP相关选项,并配置TFTP服务器的IP地址、端口号和存储路径等参数。 2. 创建TFTP服务器进程:在系统初始化时,创建一个TFTP服务器进程,用于接收来自客户端的TFTP请求和文件输。 3. 处理TFTP请求:当客户端发送TFTP请求时,TFTP服务器进程会根据请求类型(读请求或写请求)进行相应的处理。 4. 读请求处理:如果是读请求,即客户端请求从服务器读取文件,TFTP服务器会检查文件是否存在并可读,然后逐块地将文件内容发送给客户端。 5. 写请求处理:如果是写请求,即客户端请求上文件到服务器,TFTP服务器会检查是否有足够的存储空间和权限,然后逐块地接收客户端发送的文件内容,并写入到指定的存储路径下。 6. 输结束处理:在文件输结束后,TFTP服务器会发送相应的响应消息给客户端,并关闭相关的连接。 通过以上步骤,就可以实现lwIP中使用TFTP上文件的功能。值得注意的是,在使用TFTP上文件时,需要保证服务器和客户端之间的网络连接正常,并且服务器的存储空间和权限设置正确,以确保文件输顺利完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值