Потоки в Java-приложении - PullRequest
0 голосов
/ 29 марта 2011

Привет, ребята.Я пытаюсь написать приложение для передачи файлов в 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());
        }
    }
}

Ответы [ 3 ]

1 голос
/ 29 марта 2011

вы правы, если вы хотите обрабатывать несколько соединений, вам нужно выполнить каждый запрос к серверу в одном потоке.Теория заключается в следующем ...

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(); должны идти в методе run класса, которыйрасширяет Thread.

0 голосов
/ 29 марта 2011

Чтобы определить и запустить поток вам нужна реализация класса Runnable , который передается в Thread экземпляр, в котором вы вызываете start.

Этот вопрос очень похож и даст вам место для начала.Один ответ указывает на учебник по сокету, который показывает, как использовать несколько клиентов .Если вы не читали учебники по Socket, вам определенно следует это сделать.

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

В идеале вы будете достаточно вдохновлены, чтобы прочитать Параллелизм Java на практике , удивительный справочник по параллелизму в Java.

0 голосов
/ 29 марта 2011

Вы можете реализовать интерфейс Runnable и начать фактическую работу, используя new Thread(myRunnable).start() - это простая версия.Убедитесь, что ваш код является поточно-ориентированным, иначе он будет мешать другим вашим потокам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...