Java套接字卡在readUTF()上

时间:2017-04-06 14:08:45

标签: java multithreading sockets client-server data-transfer

我试图通过Java中的套接字传输文件,我目前的服务器方法是:

  1. 创建新主题
  2. 线程使用 dos.writeUTF()
  3. 发送文件名
  4. 线程使用 dos.writeLong()
  5. 发送文件大小
  6. 线程使用 dos.write()
  7. 发送文件

    每个线程代表一个客户端, dos 是DataOutputStream的一个实例。

    现在,在客户端我做同样的事情,但阅读而不是写作:

    1. 使用 dis.readUTF()
    2. 读取文件名
    3. 使用 dis.readLong()
    4. 读取文件大小
    5. 使用 dis.read()
    6. 读取文件

      其中 dis 是DataInputStream的一个实例 问题是:当发送一个文件时,一切正常,但是当我尝试一个接一个地发送3个文件时,看起来服务器正在按预期正确地将所有内容写入流但是客户端(在第一个文件之后,意味着这从第二个文件开始发生)停留在 dis.readUTF()上并且无法继续前进。

      我已经尝试了几天,但无法解决问题 这是源代码:

      服务器

      Main.java

       public class Main {
          public static void main(String[] args) {
              boolean boolDebug = true;//TODO REMOVE THIS!!
              ServerSocket serverSock = null;
              List<Socket> clientSocks;
              List<ClientThread> clientThreads;
              try {
                  serverSock = new ServerSocket(9090);
              } catch(Exception e){
                  e.printStackTrace();
              }
              clientSocks = new ArrayList<>();
              clientThreads = new ArrayList<>();
              ServerSocket finalServerSock = serverSock;
      
              System.out.println();
              System.out.println("Listening for incoming connections\n");
              new Thread(){
                  @Override
                  public void run() {
                      super.run();
                      while (true) {
                          try {
                              Socket newSock = finalServerSock.accept();
                              clientSocks.add(newSock); //FIXME Remove sockets when closed
                              Thread thread = new ClientThread(newSock, usr, psw);
                              thread.start();
                              clientThreads.add((ClientThread)thread);
                          } catch (Exception e) {
                              e.printStackTrace();
                          }
                      }
                  }
              }.start();
          }
      }
      

      ClientThread.java

      public class ClientThread extends Thread {
          private Socket socket;
          private DataInputStream inStream;
          private DataOutputStream outStream;
          private String dbUser;
          private String dbPassword;
      
          public ClientThread(Socket socket, String DbUser, String DbPass) {
              this.socket = socket;
              this.dbUser = DbUser;
              this.dbPassword = DbPass;
          }
      
          @Override
          public void run() {
              try {
                  inStream = new DataInputStream(socket.getInputStream());
                  outStream = new DataOutputStream(socket.getOutputStream());
                  sendFile("a.txt");
                  sendFile("b.txt");
                  sendFile("c.txt");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
      
          void sendFile(String file){
              try {
                  File f = new File(file);
                  outStream.writeUTF(file);
                  outStream.writeLong(f.length());
                  FileInputStream fis = new FileInputStream(f);
                  byte[] buffer = new byte[4096];
      
                  while (fis.read(buffer) > 0) {
                      outStream.write(buffer);
                  }
                  fis.close();
              }catch(Exception e){
                  e.printStackTrace();
              }
      
          }
          int getSize(byte[] buffer,long remaining){
              try {
                  return Math.toIntExact(Math.min(((long) buffer.length), remaining));
              }catch(ArithmeticException e){
                  return 4096;
              }
          }
      
      }
      

      客户端: Main.java

      class Main {
      
          static int getSize(byte[] buffer, long remaining) {
              try {
                  return Math.toIntExact(Math.min(((long) buffer.length), remaining));
              } catch (ArithmeticException e) {
                  return 4096;
              }
          }
      
          static void saveFile(Socket clientSock,DataInputStream dis) throws IOException {
      
              String fileName = dis.readUTF();
              File f = new File(fileName);
              FileOutputStream fos = new FileOutputStream(f);
              byte[] buffer = new byte[4096];
      
              long filesize = dis.readLong();
              int read = 0;
              int totalRead = 0;
              long remaining = filesize;
      
              while ((read = dis.read(buffer, 0, getSize(buffer, remaining))) > 0) {
                  totalRead += read;
                  remaining -= read;
                  System.out.println("read " + totalRead + " bytes.");
                  fos.write(buffer, 0, read);
              }
              fos.close();
          }
      
          public static void main(String[] args) throws Exception {
              Socket sock = new Socket("192.168.2.17", 9090);
              DataInputStream dis = new DataInputStream(sock.getInputStream());
              saveFile(sock,dis);
              saveFile(sock,dis);
              saveFile(sock,dis);
      
          }
      }
      

      非常感谢,期待解决这个问题:(

1 个答案:

答案 0 :(得分:0)

通过更改

修复
while (fis.read(buffer) > 0) {
    outStream.write(buffer);
}

int count;
while ((count = fis.read(buffer)) > 0) {
    outStream.write(buffer, 0, count);
}

服务器端的ClientThread.java内部