2016-04-08 27 views
0

我做了一個基本的聊天程序,它也發送,它的不完整。一切運行良好,除了當我發送一個文件,我的程序收到它沒有任何問題,但它提供了一個套接字關閉錯誤。也發送文件的Java聊天程序

CLIENT

import java.net.*; 
import java.io.*; 

public class chatClnt { 

    public static int PORT = 6666; 
    public static String IP_ADDR = "192.168.15.1"; 
    public static String F = "FILE MODE"; 

    public static void main(String[] ar) { 

     try { 
      InetAddress ipAddress = InetAddress.getByName(IP_ADDR); 

      System.out.println("\nconnecting......"); 
      Socket socket = new Socket(ipAddress, PORT); 
      System.out.println("\nconnected"); 

      InputStream sin = socket.getInputStream(); 
      OutputStream sout = socket.getOutputStream(); 

      DataInputStream in = new DataInputStream(sin); 
      DataOutputStream out = new DataOutputStream(sout); 

      BufferedReader keyboard = new BufferedReader(new   InputStreamReader(System.in)); 

      String line = null; 
      String fname = null; 

      while (true) { 
       System.out.println("\nYou(Plain Text):>"); 
       line = keyboard.readLine(); 
       out.writeUTF(line); 
       out.flush(); 
       if (line.equals(F)) { 
        //Sending File 
        OutputStream fout = socket.getOutputStream(); 
        FileInputStream fis = null; 
        BufferedInputStream bis = null; 
        try { 
         System.out.println("Enter the path: "); 
         fname = keyboard.readLine(); 
         File myFile = new File(fname); 
         byte[] mybytearray = new byte[(int)myFile.length()]; 
         fis = new FileInputStream(myFile); 
         bis = new BufferedInputStream(fis); 
         bis.read(mybytearray,0,mybytearray.length); 

         fout = socket.getOutputStream(); 
         System.out.println("Sending " + fname + "(" + mybytearray.length + " bytes)"); 
         fout.write(mybytearray,0,mybytearray.length); 
         fout.flush(); 
         System.out.println("Done."); 
        } finally { 
         if (bis != null) bis.close(); 
         if (fout != null) fout.close(); 
        } 


        line = in.readUTF(); // wait for the server to send a line of text. 
        System.out.println("\nSender(Plain Text):> " + line); 
        System.out.println(); 
       } 
      } 
     } catch(Exception x) { 
      x.printStackTrace(); 
     } 
    } 
} 

服務器

import java.net.*; 
import java.io.*; 


public class chatSrv { 

    public static int PORT = 6666; 
    public static String F = "FILE MODE"; 
    public final static String FILE_TO_RECEIVE = "received.txt"; 
    public final static int FILE_SIZE = 999999999; 

    public static void main(String[] ar) { 

     try { 
      ServerSocket ss = new ServerSocket(PORT); 
      System.out.println("\nconnecting..."); 
      Socket socket = ss.accept(); 

      System.out.println("\nconnected"); 
      System.out.println(); 

      InputStream sin = socket.getInputStream(); 
      OutputStream sout = socket.getOutputStream(); 

      DataInputStream in = new DataInputStream(sin); 
      DataOutputStream out = new DataOutputStream(sout); 

      String line = null; 
      int bytesRead; 
      int current = 0; 

      while (true) { 
       line = in.readUTF(); 

       //Receiving File 
       if (line.equals(F)) { 
        FileOutputStream fos = null; 
        BufferedOutputStream bos = null; 
        try { 
         byte [] mybytearray = new byte [FILE_SIZE]; 
         fos = new FileOutputStream(FILE_TO_RECEIVE); 
         bos = new BufferedOutputStream(fos); 
         bytesRead = sin.read(mybytearray,0,mybytearray.length); 
         current = bytesRead; 

         do { 
          bytesRead = sin.read(mybytearray, current, (mybytearray.length-current)); 
          if (bytesRead >= 0) current += bytesRead; 
         } while (bytesRead > -1); 

         bos.write(mybytearray, 0 , current); 
         bos.flush(); 
         System.out.println("File " + FILE_TO_RECEIVE+ " downloaded (" + current + " bytes read)"); 
        } finally { 
         if (fos != null) fos.close(); 
         if (bos != null) bos.close(); 
        } 

        System.out.println("\nSender(Plain Text):> " + line); 
        BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in)); 

        System.out.println("\nYou(Plain Text):>"); 
        line = keyboard.readLine(); 
        out.writeUTF(line); 
        out.flush(); 
        System.out.println(); 
       } 
      } 
     } catch(Exception x) { 
      x.printStackTrace(); 
     } 
    } 
} 
+0

你可以請發佈實際的錯誤?也是次要的編碼樣式註釋,當您導入時嘗試導入特定的包而不是'import java.net。*'。這是一個很好的習慣。 – wiredniko

+0

remove fout.close();您正在永久運行while循環,並在收到一次hte文件後關閉,這意味着在單個文件之後流被關閉,因此它將無法再從該流中讀取數據 –

+0

關於刪除' f.out.close()'會掛起程序,因爲文件永遠不會關閉 –

回答

1

當您關閉套接字的輸出流,該關閉套接字爲好。 documentation說:

關閉返回的OutputStream將關閉相關的套接字。

所以你不能關閉流。但是,如果你不關閉它,你將永遠不會在接收端獲得-1

因此,基本上,您不能使用從磁盤讀取文件時使用的相同讀取過程。您需要設計一個協議,使您可以在保持流打開的同時讀取文件。可能的策略:

  • 爲此打開第二個套接字。例如,在可用端口上打開一個套接字,然後向服務器發送一條消息,告知它應該使用此端口號連接到另一個套接字。然後你可以通過另一個套接字發送整個文件並關閉它。或者讓服務器打開第二個套接字並告訴您要連接的端口號。這是ftp協議使用的策略。
  • 預先以字節爲單位發送文件的長度,在接收端讀取多個字節。這是HTTP使用的策略,例如,當它發送Content-length:標題時。

請記住,文件可能會很長,所以如果你決定發送的長度,使用long而非int

+0

請仔細請幫助我更精確一點點 –

+0

如果我不關閉'OutputStream'程序不會前進,我應該怎麼做 –

+0

@SiddharthMazumdar正如我所說的,你不能只是決定不關閉它 - 因爲你永遠不會在另一端得到-1,它只會等待更多的輸入。相反,您應該根據其中一種策略重新考慮您的協議。 – RealSkeptic

相關問題