Отправка файла от одного клиента другому клиенту с помощью сокета в Java

Привет всем, я пытаюсь разработать приложение для передачи / отправки файла, как работает SKYPE. Поэтому я использую сокет для передачи файла с одного компьютера (клиента) на другой компьютер (клиент) . Я могу передать файл с одного клиента на сервер, используя это. code.But, когда я пытаюсь отправить один и тот же файл с сервера на второй клиент. Он передается с 0 байтами и дает исключение закрытия сокета, поэтому я пытаюсь создать новый объект сокета на стороне клиента. Так что теперь исключение не приходит, но файл не передается клиенту. После отладки я обнаружил, что файл успешно отправляется клиенту сервером, но на стороне клиента сокет не может прочитать данные и ждать данных. Я не могу найти лучшего решения. Если кто-нибудь знает что-нибудь об этом, пожалуйста Скажите мне. Если у вас есть какое-либо другое решение для передачи файлов, чем также скажите мне. Заранее спасибо Ниже приведен мой код

 Server code:

public class ChatServer
{ 

 serversocket = new ServerSocket(1436);
 thread = new Thread(this);
 thread.start();

 /*************Thread Implementation***************/
public void run()
{
    /*********Accepting all the client connections and create a seperate thread******/
    while(thread != null)
    {
        try
        {
            /********Accepting the Server Connections***********/
            socket = serversocket.accept();             

  /******* Create a Seperate Thread for that each client**************/
            chatcommunication = new ChatCommunication(this,socket);

            thread.sleep(THREAD_SLEEP_TIME);    
        }
        catch(InterruptedException _INExc)  { ExitServer(); }
        catch(IOException _IOExc)           { ExitServer(); }   
    }   
}

protected void SendGroupFile(Socket ClientSocket, String FileName,String GroupName,String UserName) throws IOException
{
    try
    {
     // receive file from Client
      byte [] mybytearray  = new byte [filesize];
      InputStream is = socket.getInputStream();
      FileOutputStream fos = new FileOutputStream(Filepath);
      BufferedOutputStream bos = new BufferedOutputStream(fos);
      int bytesRead = is.read(mybytearray,0,mybytearray.length);
      current = bytesRead;

          do {
           bytesRead =is.read(mybytearray, current, (mybytearray.length-current));
           System.out.println("Reading Bytes server"+bytesRead); 
           if(bytesRead >= 0) 
               current += bytesRead;
         } while(bytesRead > -1);

      bos.write(mybytearray,0,current);
      bos.flush();
      bos.close();



    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

      /*****    Function To Send a File to Client   **********/
protected void SendGroupFileClient(Socket ClientSocket, String FileName,String GroupName,String UserName)
{
        try {
            int m_userListSize = userarraylist.size();

                clientobject = GetClientObject(GroupName);

                 if(clientobject != null)
                for(G_ILoop = 0; G_ILoop < m_userListSize; G_ILoop++)
                {

                    clientobject = (ClientObject) userarraylist.get(G_ILoop);
                    if((clientobject.getGroupName().equals(GroupName)) && (!(clientobject.getUserName().equals(UserName))))
                    {   
                   {    

                     File myFile = new File (Filepath);
                     byte [] mybytearray  = new byte [(int)myFile.length()];
                     FileInputStream fis = new FileInputStream(myFile);
                     BufferedInputStream bis = new BufferedInputStream(fis);
                     bis.read(mybytearray,0,mybytearray.length);
                     os = socket.getOutputStream();
                     System.out.println("Sending...");
                     os.write(mybytearray,0,mybytearray.length);
                     os.flush();
                     os.close();
             }  

        }catch(IOException _IOExc) 
        {
            _IOExc.printStackTrace();   
        }
}
}

ChatCommunication .java

public class ChatCommunication implements Runnable,CommonSettings
{
   Thread thread;
Socket socket;
DataInputStream inputstream;
String RFC;
ChatServer Parent;

     /********Initialize the Socket to the Client***********/
ChatCommunication(ChatServer chatserver,Socket clientsocket)
{               
  Parent = chatserver;
    socket = clientsocket;  
    try 
    {       
    inputstream = new DataInputStream(new  BufferedInputStream(socket.getInputStream()));       
    }catch(IOException _IOExc) { }
    thread = new Thread(this);
    thread.start(); 
}

public void run()
{
    while(thread != null)
    {
        try {               
            RFC = inputstream.readLine();

            if(RFC.startsWith("FILEGRUP"))
            {
                Parent.SendGroupFile(socket,RFC.substring(9,RFC.indexOf("!")),RFC.substring(RFC.indexOf("!")+1,RFC.indexOf("*")),RFC.substring(RFC.indexOf("*")+1));    
            }

            if(RFC.startsWith("FILEGET"))
            {
                Parent.SendGroupFileClient(socket,RFC.substring(8,RFC.indexOf("!")),RFC.substring(RFC.indexOf("!")+1,RFC.indexOf("*")),RFC.substring(RFC.indexOf("*")+1));  
            }


        }catch(Exception _Exc) 
         {
            Parent.RemoveUserWhenException(socket);QuitConnection();
         }  
    }
}

Код клиента

  class Client extends JFrame
 {
  ServerName="192.168.1.103";
  ServerPort=1436;

Client()
 {
  socket = new Socket(ServerName,ServerPort);
  SendGroupFileToServer(Filepath,SelectedGroup);    
}

 /*******Function To Send File To Server and receiving the file ***********/
protected void SendGroupFileToServer(String FileName, String ToGroup)
{
try {

dataoutputstream.writeBytes(FileName.concat("!").concat(ToUser)+"\r\n");
//send file to sever
           File myFile = new File (FileName.substring(9));
           byte [] mybytearray  = new byte [(int)myFile.length()];
           FileInputStream fis = new FileInputStream(myFile);
           BufferedInputStream bis = new BufferedInputStream(fis);
           bis.read(mybytearray,0,mybytearray.length);
           OutputStream os = socket.getOutputStream();
           System.out.println("Sending...");
           os.write(mybytearray,0,mybytearray.length);
           os.flush();
           os.close();
           System.out.println("File successfully Sended  to server");
          }catch(IOException _IoExc) { QuitConnection(QUIT_TYPE_DEFAULT);}  


               try {
          socket1 = new Socket(ServerName,ServerPort); //Creating new Socket                                    
          dataoutputstream = new DataOutputStream(socket1.getOutputStream());
          dataoutputstream.writeBytes("FILEGET"+FileName.concat("!").concat(ToGroup+"*"+UserName)+"\r\n");  //sending string to server           

    } catch (IOException e1) {
        e1.printStackTrace();
    }

    // receive file sended by server
      byte [] mybytearray  = new byte [filesize];
      InputStream is;
    try {
        is = socket1.getInputStream();

      FileOutputStream fos = new FileOutputStream(Filepath);
      BufferedOutputStream bos = new BufferedOutputStream(fos);
      int bytesRead = is.read(mybytearray,0,mybytearray.length);
      current = bytesRead; //up to this working fine

      do {
           bytesRead =is.read(mybytearray, current, (mybytearray.length-current)); //not reading the file data sent by server just waiting and not go ahead 
           if(bytesRead >= 0) 
               current += bytesRead;
         } while(bytesRead > -1);

      bos.write(mybytearray,0,current);
      bos.flush();
      bos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    } 

}

2 ответа

Здесь так много проблем, что трудно понять, с чего начать.

  1. thread.sleep() в accept() Цикл буквально пустая трата времени. Это не служит никакой полезной цели, за исключением, возможно, снижения скорости приема клиентов. Если это не было вашим намерением, не делайте этого.

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

  3. readLine() возвращает ноль в EOS, на котором вы должны закрыть сокет, прекратить чтение и выйти из потока. Вы не проверяете это, и поэтому вы пропускаете все три из этих необходимых шагов. Не делай этого.

  4. Вы строите DataInputStream вокруг BufferedInputStream для использования при чтении команд, но вы не передаете его методам, которые обрабатывают эти команды. Вы просто проходите розетку. Поэтому вы теряете данные. Не делай этого. Каждая часть программы должна использовать один и тот же поток ввода или считыватель для сокета.

  5. Вы читаете весь файл в память. Это (а) предполагает, что размер файла вписывается в int; (б) не масштабируется до больших файлов; (c) тратит пространство и (d) добавляет задержку. Не делай этого.

  6. Вы игнорируете результат чтения () в этот буфер и предполагаете, что он был заполнен. Вы не можете сделать это. Правильный способ копирования потоков в Java показан ниже. Это работает с буфером любого размера, например, 8192, для ввода любой длины и не требует буферизации всего ввода в памяти. Вы можете использовать этот цикл как на клиенте при отправке файла, так и на сервере при его получении.

    while ((count = in.read(buffer)) > 0)
    {
      out.write(buffer, 0, count);
    }
    
  7. Аналогично (4) выше, вы используете DataOutputStream вокруг BufferedOutputStream для некоторых вещей и поток вывода сокета напрямую для других. Не делай этого. Все части программы должны иметь одинаковый выходной поток или записывающее устройство для сокета.

  8. Вам не нужно flush() до close(); это происходит автоматически.

  9. По какой-то причине после отправки файла вы создаете новое соединение и отправляете другую команду. Вы даже не закрываете соединение впоследствии. У сервера не будет простого способа узнать, что это соединение и эта команда ссылаются на файл, только что отправленный в приведенном выше коде. Это также избыточно, поскольку получение окончательного EOS сообщает серверу, что файл был успешно отправлен. Не делай этого. Если вам необходимо отправить дополнительную информацию с файлом, сначала отправьте ее перед тем же файлом по тому же соединению.

  10. Ссылка, на которую вы ссылаетесь, показывает многие из вышеперечисленных вопросов. Постарайтесь найти достойную отправную точку.

Это решение. Пожалуйста, примените эту логику к своему коду.

Я могу отправить файл с сервера на клиент и клиент на сервер.

Проверьте следующий код, чтобы отправить файл с клиента на сервер. Работает отлично.

Если у вас есть какие-либо проблемы, дайте мне знать.

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

public class ServerRecieveFile {
public static void main(String[] args) throws IOException {// TODO Auto-enerated method stub int filesize=1022386; 
int bytesRead; int currentTot= ;
ServerSocket serverSocket=new ServerSocket(15123); 
Socket socket=rverSocket.accept();
byte [] bytearray  = new byte [filesize];
InputStream is=socket.getInputStream();
File copyFileName=new File("c:/Files Sockets/2.txt");
FileOutputStream fos = new FileOutputStream(copyFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray,0,bytearray.length);
currentTot = bytesRead;
do {
bytesRead =is.read(bytearray, currentTot, (bytearray.length-currentTot)); if(bytesRead >= 0)
 currentTot += bytesRead;
} while(bytesRead > -1);
bos.write(bytearray, 0 , currentTot);
bos.flush();
 bos.close();
socket.close();
 }
}

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

public class ClientSendFile {
public static void main(String[] args) throws UnknownHostException, IOException {// TODO Auto-generated method stub
Client client=new Client();
Socket socket = new Socket(InetAddress.getLocalHost(),15123);
System.out.println("Accepted connection : " + socket);
File transferFile = new File ("c:/Files Sockets/1.txt");
byte [] bytearray  = new byte (int)transferFile.length()];
FileInputStream fin = new FileInputStream(transferFile);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray,0,bytearray.length);
OutputStream os = socket.getOutputStream();
System.out.println("Sending Files...");
os.write(bytearray,0,bytearray.length);
os.flush();
socket.close();
System.out.println("File transfer complete");
 }
}
Другие вопросы по тегам