2011-03-29 92 views
0

嘿家伙。我正在尝试在java中编写文件传输应用程序,到目前为止它一直正常:我启动服务器和客户端,然后传输文件。我无法将多个客户端连接到同一台服务器。我GOOGLE了它,发现我的服务器端应该运行在线程中。我如何使用我的应用程序做到这一点?谢谢。Java应用程序中的线程

服务器:

package filesharing; 
import java.io.*; 
import java.net.*; 

public class Server 
{ 
    public static void main(String args[])throws Exception 
    { 
     System.out.println("Server pornit..."); 

     /* Asteapta pe portul 1412 */ 

     ServerSocket server = new ServerSocket(1412); 

     /* Accepta socketul */ 

     Socket sk = server.accept(); 

     System.out.println("Client acceptat de catre server pe portul: "+server.getLocalPort()); 
     InputStream input = sk.getInputStream(); 
     BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream())); 
     BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream())); 

     /* Citeste calea fisierului */ 
     String filename = inReader.readLine(); 

     if (!filename.equals("")){ 

      /* Trimite status READY catre client */ 

      outReader.write("READY\n"); 
      outReader.flush(); 
     } 

     /* Creaza fila noua in directorul tmp */ 
     FileOutputStream wr = new FileOutputStream(new File("C://tmp/" + filename)); 

     byte[] buffer = new byte[sk.getReceiveBufferSize()]; 

     int bytesReceived = 0; 

     while((bytesReceived = input.read(buffer))>0) 
     { 
      /* Scrie in fila */ 
      wr.write(buffer,0,bytesReceived); 
     } 
    } 
} 

客户:

package filesharing; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.net.*; 
import java.io.*; 

public class Client extends JFrame implements ActionListener { 

    private JTextField txtFile; 

    public static void main(String args[]){ 

     /* Creare pannel client */ 

     Client clientForm = new Client(); 
     clientForm.Display(); 
    } 

    public void Display(){ 

     JFrame frame = new JFrame(); 
     frame.setTitle("Client"); 

     FlowLayout layout = new FlowLayout(); 
     layout.setAlignment(FlowLayout.LEFT); 

     JLabel lblFile = new JLabel("Fisier:"); 

     txtFile = new JTextField(); 
     txtFile.setPreferredSize(new Dimension(150,30)); 

     JButton btnTransfer = new JButton("Transfer"); 
     btnTransfer.addActionListener(this); 

     JPanel mainPanel = new JPanel(); 
     mainPanel.setLayout(layout); 
     mainPanel.add(lblFile); 
     mainPanel.add(txtFile); 
     mainPanel.add(btnTransfer); 

     frame.getContentPane().add(mainPanel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 

    } 

    public void actionPerformed(ActionEvent e) { 

     /* Casuta File Open Dialog pentru selectarea fisierului */ 

     JFileChooser fileDlg = new JFileChooser(); 
     fileDlg.showOpenDialog(this); 
     String filename = fileDlg.getSelectedFile().getAbsolutePath(); 
     txtFile.setText(filename); 

     try{ 

      /* Incearca conectarea la serverul localhost pe portul 1412 */ 

      Socket sk = new Socket("localhost", 1412); 
      OutputStream output = sk.getOutputStream(); 

      /* Trimite numele fisierului la server */ 

      OutputStreamWriter outputStream = new OutputStreamWriter(sk.getOutputStream()); 
      outputStream.write(fileDlg.getSelectedFile().getName() + "\n"); 
      outputStream.flush(); 

      /* Asteapta raspunsul de la server */ 

      BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream())); 

      String serverStatus = inReader.readLine(); // Citeste prima linie 

      /* Daca serverul e READY trimite fisierul */ 

      if (serverStatus.equals("READY")){ 

       FileInputStream file = new FileInputStream(filename); 

       byte[] buffer = new byte[sk.getSendBufferSize()]; 

       int bytesRead = 0; 

       while((bytesRead = file.read(buffer))>0) 
       { 
        output.write(buffer,0,bytesRead); 
       } 

       output.close(); 
       file.close(); 
       sk.close(); 

       JOptionPane.showMessageDialog(this, "Transfer complet"); 

      } 
     } 
     catch (Exception ex){ 
      /* Catch pentru eventuale erori */ 
      JOptionPane.showMessageDialog(this, ex.getMessage()); 
     } 
    } 
} 
+2

现在,你已经找到你需要使用线程,下一步就是阅读[Java线程教程](http://download.oracle.com/javase/tutorial/essential/concurrency/)。如果你不明白它是如何工作的,那么让别人为你写就是没有用的。 – 2011-03-29 14:26:24

回答

1

如果你想处理多个连接,你需要在单个线程中运行每个服务器请求,那么你是对的。背后的理论是以下...

while (true) 
    accept a connection ; 
    create a thread to deal with the client ; 
end while 

或多个Java-相似:

while(true) { 
    clientSocket = serverSocket.accept(); 
    YourWorkerThread thread = new YourWorkerThread(clientSocket); 
    thread.start(); 
} 

在哪里... YourWorkerThread是延伸Thread并实现了一种方法run一类,其中的逻辑服务器位于。

因此,看看你的服务器端代码,Socket sk = server.accept();之后的所有代码行应该在延伸Thread的类的方法run中。

+0

完成。非常感谢。另一个问题。就是Java能够从客户端从服务器中的文件结构打开一个JFileChooser(例如我想连接到服务器,浏览服务器上的文件,并将其复制到客户端)。 – 2011-03-29 19:34:27

+0

不,那是绝对不可能的。除非你实现一个客户,要求在目录中的文件,并列出它们在客户端JFileChooser中。总之,你需要实现通信协议。另见http://stackoverflow.com/questions/1732179/jfilechooser-browsing-a-remote-file-system – 2011-03-30 08:50:26

+0

感谢您的帮助。我想知道RMI是否有助于解决这个问题。 – 2011-03-30 16:09:28

0

你可能实现的接口Runnable UND开始使用new Thread(myRunnable).start()实际工作 - 这是简单的版本。确保你的代码是线程安全的,否则会干扰你的其他线程。

0

define and start a thread你需要传递给在其上调用start一个Thread实例的类Runnable的实现。

This question是非常相似,并会为您提供一个开始的地方。一个答案指向a socket tutorial that shows how to use multiple clients。如果你还没有阅读Socket教程,你绝对应该这样做。

但不要停下来了解线程的基本知识,否则会遇到问题。并发性是一个难题。您需要阅读Java concurrency的伟大世界。

理想情况下,你会得到启发够看了Java Concurrency in Practice,在Java并发上一个了不起的参考。