-2

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

聊天通讯.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();
    }
    } 

}

4

2 回答 2

4

这里有很多问题,很难知道从哪里开始。

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

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

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

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

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

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

    while ((count = in.read(buffer)) > 0)
    {
      out.write(buffer, 0, count);
    }
    
  7. 与上面的 (4) 类似,您在 BufferedOutputStream 周围使用 DataOutputStream 来处理某些事情,而直接使用套接字输出流来处理其他事情。不要那样做。程序的所有部分必须为套接字提供相同的输出流或编写器。

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

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

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

于 2012-10-27T05:30:16.240 回答
-1

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

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

检查以下代码以将文件从客户端发送到服务器。它工作得很好。

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

服务器端代码:

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");
 }
}
于 2013-01-31T20:01:29.037 回答