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