2014-02-21 54 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

服務器只在發生錯誤後纔讀取整個文件。我已經嘗試了一系列從1KB文本文件到3.5GB視頻文件的文件類型和大小。上傳的文件完整且功能齊全(意味着它們不會損壞)。錯誤仍然發生 – 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

這不會工作。這裏的'是'將超出範圍。 – 1xQ

+0

只需用'clientSocket.getInputStream()'更改'is'即可。
adt14

0

您正在爲每個事務創建新流並關閉它們。這會關閉套接字並導致下一次發生異常。

但是這種技術無論如何都是無效的。您應該在套接字的生命週期中使用相同的流。您還需要安排對等方知道您要發送的文件中有多少數據,通常通過提前發送並讓對等方精確讀取多個字節,而不是像現在這樣讀取數據流結尾。

+0

我編輯了我的服務器代碼,以在套接字存在期間使用相同的流。同樣的錯誤仍然發生。 – 1xQ