2011-03-29 9 views
0

안녕 얘들 아. 내가 자바에서 파일 전송 응용 프로그램을 작성하려고하고 지금까지 괜찮 았어 : 나는 서버와 클라이언트를 시작한 다음 파일을 전송합니다. 여러 클라이언트를 동일한 서버에 연결하는 데 문제가 있습니다. 나는 그것을 봤 거든 내 서버 쪽 스레드에서 실행해야한다는 것을 알게되었습니다. 신청서와 함께 어떻게 할 수 있습니까? 감사.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/)를 읽는 것입니다. 그것이 어떻게 작동하는지 이해하지 못하면 누군가에게 당신을 위해 글을 쓰게하는 것은 쓸모가 없습니다. –

답변

1

단일 스레드에서 모든 서버 요청을 실행하는 데 필요한 여러 연결을 처리하려는 경우에 맞습니다. 이 이론은 뒤에 ...

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

또는 다음 더 자바 - 동일 조건 변경 허락 : YourWorkerThreadThread를 확장하는 방법 run를 구현하는 클래스가

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

어디 ... 어디의 논리 서버가 있습니다.

서버 측 코드를 살펴보면 이후의 모든 코드 행은 Thread으로 확장되는 클래스 run에 있어야합니다.

+0

완료. 고마워. 다른 질문. 자바는 클라이언트 측에서 서버의 파일 구조로 JFileChooser를 열 수 있습니까 (예 : 서버에 연결하고 서버에서 파일을 찾아 클라이언트에 복사하려는 경우). –

+0

아니요, 확실히 불가능합니다. 디렉토리의 파일을 요구하고 클라이언트의 JFileChooser에 파일을 나열하는 클라이언트를 구현하지 않는 한. 요약하면 통신 프로토콜을 구현해야합니다. http://stackoverflow.com/questions/1732179/jfilechooser-browsing-a-remote-file-system –

+0

도움을 주셔서 감사합니다. RMI가 그 문제를 해결하는 데 도움이 될지 궁금합니다. –

0

당신은 Runnable 싶게가 new Thread(myRunnable).start()를 사용하여 실제 작업을 시작 인터페이스를 구현하는 - 즉 간단한 버전의합니다. 코드가 스레드로부터 안전한지 확인하십시오. 그렇지 않으면 다른 스레드와 충돌하게됩니다.

0

define and start a threadRunnable의 구현은 start이라고하는 Thread 인스턴스로 전달되어야합니다.

This question은 매우 유사하며 시작할 장소를 제공합니다. 한 대답은 a socket tutorial that shows how to use multiple clients을 가리 킵니다. 소켓 자습서를 읽지 않았다면 꼭해야합니다.

그러나 스레딩의 기초 만 알면 멈추지 말고 문제가 발생할 것입니다. 동시성은 어려운 문제입니다. Java concurrency의 위대한 세계를 읽고 싶을 것입니다.

이상적으로는 Java의 동시성에 대한 놀라운 참조 인 Java Concurrency in Practice을 읽을만큼 충분히 영감을 얻으실 수 있습니다.

관련 문제