使用java中的套接字将文件从一个客户端发送到另一个客户端

Posted

技术标签:

【中文标题】使用java中的套接字将文件从一个客户端发送到另一个客户端【英文标题】:Sending file from one client to another client using socket in java 【发布时间】:2012-10-27 05:11:30 【问题描述】:

大家好, 我正在尝试开发用于传输/发送文件的应用程序,如 SKYPE 作品。所以我使用套接字将文件从一台计算机(客户端)传输到另一台计算机(客户端)。我能够将文件从一个客户端传输到服务器使用this。代码。但是当我尝试将相同的文件从服务器发送到第二个客户端时。它以 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();
    
     

【问题讨论】:

代码太多,无法阅读。风格上的暴行太多了。对不起。 好的...忘记代码。如果您对使用套接字或任何其他方式将文件从一个客户端传输到另一个客户端有任何想法,请告诉我...... 什么异常?顺便说一句sscce.org 【参考方案1】:

这里的问题太多了,很难知道从哪里开始。

    accept() 循环中的thread.sleep() 实际上是在浪费时间。除了可能限制接受客户端的速率之外,它没有任何用处。如果这不是您的意图,请不要这样做。

    您在捕获异常时所做的一切就是退出服务器,甚至不打印异常消息。所以当出现问题时,就像这里一样,你不可能知道它是什么。不要那样做。

    readLine() 在 EOS 返回 null,此时您必须关闭套接字、停止读取并退出线程。您没有对此进行测试,因此您省略了所有三个必需的步骤。不要那样做。

    您正在围绕BufferedInputStream 构造一个DataInputStream 以在读取命令时使用,但您没有将它传递给处理这些命令的方法。你只是通过套接字。因此,您正在丢失数据。不要那样做。程序的每个部分都必须为套接字使用相同的输入流或读取器。

    您正在将整个文件读入内存。这(a)假设文件大小适合int; (b) 不能扩展到大文件; (c) 浪费空间,(d) 增加延迟。不要那样做。

    您忽略了 read() 到该缓冲区的结果并假设它已被填充。你不能那样做。在 Java 中复制流的正确方法如下所示。这适用于任何大小的缓冲区,例如8192,对于任何长度的输入,并且不需要您将整个输入缓冲到内存中。您可以在发送文件时在客户端使用此循环,在接收文件时在服务器端使用此循环。

    while ((count = in.read(buffer)) > 0)
    
      out.write(buffer, 0, count);
    
    

    与上面的 (4) 类似,您在 BufferedOutputStream 周围使用 DataOutputStream 来处理某些事情,而直接使用套接字输出流来处理其他事情。不要那样做。程序的所有部分都必须使用相同的输出流或套接字编写器。

    close()之前不需要flush();它会自动发生。

    由于某种原因,在发送文件后,您正在创建一个新连接并发送另一个命令。之后您甚至都没有关闭连接。服务器没有简单的方法知道这个连接和这个命令引用了刚刚在上面的代码中发送的文件。这也是多余的,因为最终 EOS 的收据告诉服务器文件已成功发送。不要这样做。如果您需要随文件发送更多信息,请先在同一连接上发送文件,然后再发送。

    您引用的参考文献展示了上述许多问题。努力寻找一个有信誉的起点。

【讨论】:

对不起,但我之前没有使用过文件和套接字,所以请你简单地告诉我你的第三步(建议)。我不明白。:( @krushnakant 'Returns null'、'close the socket'、'stop reading'和'exit the thread'对我来说似乎都很清楚。【参考方案2】:

这就是解决方案。请将此逻辑应用于您的代码。

我能够将文件从服务器发送到客户端以及从客户端发送到服务器。

检查以下代码以将文件从客户端发送到服务器。效果很好。

如果您有任何问题,请告诉我。

服务器端代码:

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");
 

【讨论】:

致 Shanahul:最初的问题是询问客户端->服务器->客户端文件传输,并且可能在服务器端没有临时存储 甚至不编译。

以上是关于使用java中的套接字将文件从一个客户端发送到另一个客户端的主要内容,如果未能解决你的问题,请参考以下文章

无法在java中的2台PC套接字之间将客户端连接到服务器

QTcp [服务器和套接字]:无法读取发送的文件

如何使用 node.js 和 socket.io 将文件从 iPhone 发送到另一台 iPhone?

如何将“requests.get”的结果发送到另一个套接字?

如何将数据从 Web 服务中的一种方法发送到另一种方法

操作系统