正在努力学习的小白袁 2023-06-25 19:46 采纳率: 90%
浏览 24
已结题

java网络编程连续发送文件和字符串遇到的问题

想着用java的网络编程,客户端先发送文件,服务端接收,客户端在发送一条语句,服务端已接受
但结果是文件没有完全接受(已保存,但是打不开),语句发出去却显示null
服务端代码

package Test;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Test_Server {
    public static void main(String[] args) throws IOException {
        ServerSocket sockets=new ServerSocket(8899);
        Socket socket = sockets.accept();
        BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\null2.jpg");


        int i=0;
        byte[] bytes=new byte[1024];
        while((i=bufferedInputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes,0 ,i);
        }
        System.out.println("已接受文件");

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String s = bufferedReader.readLine();
        System.out.println(s);

//        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
//        bufferedOutputStream.write("copyRightNow".getBytes());

//        bufferedOutputStream.close();
        bufferedReader.close();
        fileOutputStream.close();
        bufferedInputStream.close();

    }
}


客户端

package Test;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class Test_Client {
    public static void main(String[] args) throws IOException {
        Socket socket=new Socket(InetAddress.getLocalHost(),8899);
        OutputStream outputStream = socket.getOutputStream();
        BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);
//
//
        byte[] bytes=getBytes();
        bufferedOutputStream.write(bytes);
        System.out.println("已发送文件");

        //发送语句
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("helloWorld");
        bufferedWriter.newLine();
        bufferedWriter.flush();
        socket.shutdownOutput();
        System.out.println("已发送语句");

        bufferedWriter.close();
        socket.close();

    }
    //获取二进制文件保存在bytes数组中
    public static byte[] getBytes() throws IOException {
        File file = new File("D:\\null.jpg");
        FileInputStream fileInputStream = new FileInputStream(file);
        int len=(int)file.length();
        byte[] bytes=new byte[len];
        int readLine;
        while((readLine= fileInputStream.read(bytes))!=-1){}
        fileInputStream.close();
        return bytes;

    }
}

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-06-25 22:58
    关注
    • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/229518
    • 你也可以参考下这篇文章:【Java练习】实现一个简单的控制台版用户登陆程序, 程序启动提示用户输入用户名密码. 如果用户名密码出错, 使用自定义异常的方式来处理
    • 你还可以看下java参考手册中的 java-学习Java语言 - 描述Java编程语言的基本概念和特点的课程。-泛型是Java编程语言的一个强大功能。它们提高了代码的类型安全性,使更多的错误可以在编译时发现。-野生动物
    • 除此之外, 这篇博客: 关于数据库中NULL的描述,下列哪些说法符合《阿里巴巴Java开发手册》中的 多选 关于异常处理,下列哪些说法是正确的:答案在文末 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
      • A. try块放到了事务代码中,catch异常后,如果需要回滚事务,必须要手动回《事务。
      • B. 在finaly块必须对文件流进行关团。
      • C. 不能在1mnaly块使用return,fnaly块中的return返回后方法结来执行,不会再执行n块中的return语句。
      • D. 循环体中避免不必要的try-catch操作。
    • 您还可以看一下 徐无忌老师的Java进阶高手课-并发编程透彻理解课程中的 什么是多线程的上下文切换,有什么影响?如何进行优化?(二)小节, 巩固相关知识点
    • 以下回答由chatgpt基于相关博客总结生成:

      针对这个问题,我建议采用以下优化方案:

      1. 客户端发送文件时应该先发送文件的长度,然后再发送文件内容,以确保服务端能够正确接收完整的文件内容。同时,需要使用缓冲区进行传输,防止数据丢失或传输错误。

      以下是Java代码示例:

      // 客户端发送文件
      File file = new File("path/to/file");
      DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
      
      // 先发送文件长度
      dos.writeLong(file.length());
      
      // 再发送文件内容
      FileInputStream fis = new FileInputStream(file);
      BufferedInputStream bis = new BufferedInputStream(fis);
      
      byte[] buffer = new byte[4096];
      int len;
      while ((len = bis.read(buffer)) > 0) {
          dos.write(buffer, 0, len);
      }
      dos.flush();
      
      // 关闭流
      bis.close();
      fis.close();
      dos.close();
      
      1. 在客户端发送完文件后,需要使用 Socket.shutdownOutput() 方法关闭输出流,以确保服务端能够及时收到文件并进入下一步处理。

      以下是Java代码示例:

      // 客户端发送完文件后关闭输出流
      socket.shutdownOutput();
      
      1. 在客户端发送字符串时,需要使用 PrintWriter 来发送字符串,并且需要在字符串前面添加一个长度,以便服务端能够正确接收字符串。在服务端接收字符串时,根据前面添加的长度来读取相应长度的字符串内容。

      以下是Java代码示例:

      // 客户端发送字符串
      String msg = "Hello World";
      PrintWriter pw = new PrintWriter(socket.getOutputStream());
      
      // 先发送字符串长度
      pw.println(msg.length());
      
      // 再发送字符串内容
      pw.println(msg);
      pw.flush();
      
      // 关闭流
      pw.close();
      
      
      // 服务端接收字符串
      BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      
      // 读取字符串长度
      int len = Integer.parseInt(br.readLine());
      
      // 读取字符串内容
      char[] buffer = new char[len];
      br.read(buffer, 0, len);
      String msg = new String(buffer);
      
      // 关闭流
      br.close();
      

      希望以上优化方案能够帮助您解决问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 7月22日
  • 已采纳回答 7月14日
  • 创建了问题 6月25日

悬赏问题

  • ¥15 机器学习预测遇到的目标函数问题
  • ¥15 python的EOFError该怎么解决?
  • ¥15 Fluent,液体进入旋转区域体积分数不连续
  • ¥15 java linux下将docx文件转pdf
  • ¥15 maven无法下载依赖包
  • ¥15 关于pycharm, Callable[[str],bool]作为方法参数使用时, lambda 类型不提示问题
  • ¥15 layui数据重载无效
  • ¥15 寻找了解qq家园纵横四海的程序猿。
  • ¥15 optisystem
  • ¥15 VB.NET画图时的撤销编程