2016-04-08 7 views
0

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

КЛИЕНТ

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(); 
     } 
    } 
} 

SERVER

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