2014-02-21 4 views
0

Я могу загрузить любой тип файла на сервер, используя следующий код. Тем не менее, сразу после загрузки заканчивается, я получаю сообщение об ошибке на сервере, который говоритЗагрузка файла с использованием сокетов

java.net.SocketException: Socket is closed Exception in thread "Thread-0" java.lang.NullPointerException at Server2Connection.run(server1.java:407) at java.lang.Thread.run(Unknown Source)

server1.java: 407 относится к линии switch (clientMsg) в коде сервера. Файл загружается правильно. Но, похоже, я ничего не делаю с инструкциями .close. После этого сервер не отключается, но клиент отключается еще раз, чтобы отключиться. Может кто-нибудь скажет мне, где я возился? Благодарю.

стороне сервера:

public BufferedReader msgFromClient() throws IOException { 
    BufferedReader receiveClientmsg = null; 

    try { 
     receiveClientmsg = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
    } catch (IOException e) { 
     System.out.println(e); 
    } 
    return receiveClientmsg; 
} 

public DataOutputStream outToClient() throws IOException { 
    DataOutputStream sendClientmsg = null; 

    try { 
     sendClientmsg = new DataOutputStream(clientSocket.getOutputStream()); 
    } catch (IOException e) { 
     System.out.println(e); 
    } 
    return sendClientmsg; 
} 

public void upload() throws IOException { 
    byte[] mybytearray = new byte[8192]; 
    InputStream is = clientSocket.getInputStream(); 
    String file_name = msgFromClient().readLine(); 
    File rqstd_upld_file = new File(SERVER_FILE_LOCATION + file_name); 

    if (rqstd_upld_file.exists()){ 
     outToClient().writeBytes("yes\n"); 
     outToClient().writeBytes("A file with the name " + file_name + " already exists on server\n"); 
     System.out.println("A file with the name " + file_name + " already exists"); 
    } 
    else { 
     outToClient().writeBytes("no\n"); 
     FileOutputStream fos = new FileOutputStream(SERVER_FILE_LOCATION +"\\"+ file_name); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 

     int count; 
     System.out.println("Downloading " + file_name + " ..."); 
     outToClient().writeBytes("Uploading. Please wait...\n"); 
     while ((count = is.read(mybytearray)) > 0){ 
      bos.write(mybytearray, 0, count); 
     } 
     System.out.println("Download Successful"); 
     is.close(); 
     bos.close(); 
    } 
} 
try { 
     while (true) { 
      //Message sent by the client 
      String clientMsg = server.msgFromClient().readLine();    

      switch (clientMsg) { 
      case "1": 
       //'Upload file' command from client 
       System.out.print("\nCommand from " + clientSocket.getInetAddress() + ":"+ clientSocket.getPort()+" : "); 
       System.out.println("Upload file"); 
       server.upload(); 
       break; 

      case "1fail": 
       //In case client fails to find the file it wants to upload 
       System.out.print("\nCommand from " + clientSocket.getInetAddress() + ":"+ clientSocket.getPort()+" : "); 
       System.out.println("Upload file"); 
       System.out.println("Client could not upload: File did not exist on client machine\n"); 
       break; 
} 
catch(IOException e){ 
     System.out.println(e); 
    } 

Клиент сторона:

while (true) { 
try{ 
Scanner scan0 = new Scanner(System.in); 
String command = scan0.nextLine(); 

switch (command) { 
case "1": 
    //Upload file 
    File file_to_upload = null; 
    System.out.print("Enter file path: "); 
    Scanner scan = new Scanner(System.in); 
    String pathname = scan.nextLine(); 
    System.out.print("Enter file name: "); 
    Scanner scan1 = new Scanner(System.in); 
    String file = scan1.nextLine(); 
    Path path = Paths.get(pathname, file); 
    file_to_upload = new File(path.toString()); 

    if (file_to_upload.exists()){ 
     outToServer.writeBytes(command + '\n'); 
     outToServer.writeBytes(file + '\n'); 
     String existsOnServer = msgFromServer.readLine(); 

     switch (existsOnServer) { 
     case "yes": 
      System.out.println('\n'+ msgFromServer.readLine() + '\n'); 
      break; 
     case "no": 
      int count; 
      System.out.println('\n'+ msgFromServer.readLine() + '\n'); 
      byte[] bytearray = new byte[8192]; 
      InputStream in = new FileInputStream(file_to_upload); 
      BufferedInputStream bis = new BufferedInputStream(in); 
      OutputStream os = client1.getOutputStream(); 
       while ((count = bis.read(bytearray)) > 0){ 
       os.write(bytearray, 0, count); 
      } 
      System.out.println("Done Uploading"); 
      os.close(); 
      in.close(); 
      bis.close(); 
      break; 
     } 
    } 
    else{ 
     System.out.println("File " + path + " does not exist\n"); 
     outToServer.writeBytes("1fail" + '\n'); 
    } 
    break; 

    case "2": 
//... 
} 
       catch(IOException e){ 
        System.out.println(e); 
        break; 
       } 
} 

ответ

-1

Вы можете закрывать клиент Strem слишком рано, не позволяя серверу дочитать форме он. Попробуйте поставить таймер перед закрытием стримера и сокета клиента. Если это сработает, вы должны подумать о более удобной синхронизации, чтобы сервер мог читать весь файл.

+0

Сервер считывает весь файл ... только после этого возникает ошибка. Я экспериментировал с различными типами файлов и размерами, начиная с текстовых файлов 1 КБ и до 3,5 ГБ видеофайлов. Загруженные файлы являются полными и функциональными (значит, они не повреждаются). Ошибка все еще возникает – 1xQ

+0

Вам не нужны таймеры или отложенные закрытия. Данные не теряются в TCP. – EJP

0

Просто добавьте новую команду для закрытия соединения с сервером.

switch (clientMsg) { 
     case "1": 
      //'Upload file' command from client 
      System.out.print("\nCommand from " + clientSocket.getInetAddress() + ":"+ clientSocket.getPort()+" : "); 
      System.out.println("Upload file"); 
      server.upload(); 
      break; 

     case "1fail": 
      //In case client fails to find the file it wants to upload 
      System.out.print("\nCommand from " + clientSocket.getInetAddress() + ":"+ clientSocket.getPort()+" : "); 
      System.out.println("Upload file"); 
      System.out.println("Client could not upload: File did not exist on client machine\n"); 
      break; 
     case "-1": 
      is.close(); 

      break; 
+0

Это не будет работать. 'is' здесь будет недоступен. – 1xQ

+0

просто измените 'is' на' clientSocket.getInputStream() '.
adt14

0

Вы создаете новые потоки для каждой транзакции и закрываете их. Это закрывает сокет и вызывает исключение, которое вы получаете в следующий раз.

Но техника в любом случае недействительна. Вы должны использовать те же потоки для жизни сокета. Вам также необходимо организовать для партнера возможность узнать, сколько данных находится в отправляемом вами файле, как правило, путем его отправки заранее, а сверстники читают точно столько же байтов, а не читают до конца потока, как у вас сейчас.

+0

Я отредактировал код сервера, чтобы использовать те же потоки на время существования сокетов. Такая же ошибка сохраняется. – 1xQ

Смежные вопросы