Threads in Java Application
Hey guys. I am trying to write a file transfer application in java and so far it's been ok: i start the server and the client and then transfer the file. I'm having trouble connecting multiple clients to the same server. I googled it and found out that my server side should run in threads. How can i do that with my application? Thanks.
Server:
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);
}
}
}
Client:
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());
}
}
}
you're right if you want to handle multiple connections you need to run every server request in a single thread. The theory behind is the following ...
while (true)
accept a connection ;
create a thread to deal with the client ;
end while
or more java-alike:
while(true) {
clientSocket = serverSocket.accept();
YourWorkerThread thread = new YourWorkerThread(clientSocket);
thread.start();
}
Where ...
YourWorkerThread
is a class that extends Thread
and implements a method run
where the logic of the server is located.
So looking at your server-side code, all the lines of code after Socket sk = server.accept();
should go in the method run
of a class that extends Thread
.
You might implement the interface Runnable
und start the actual work using new Thread(myRunnable).start()
- that's the simple version. Make sure that your code is thread safe or it will interfere with your other threads.
To define and start a thread you need an implementation of the class Runnable that is passed to a Thread instance on which you call start.
This question is very similar and will provide you a place to start. One answer points to a socket tutorial that shows how to use multiple clients. If you haven't read the Socket tutorials, you definitely should.
But don't stop at knowing just the basics of threading or you'll run into problems. Concurrency is a hard problem. You will want to read up on the great world of Java concurrency.
Ideally you will be inspired enough to read Java Concurrency in Practice, an amazing reference on concurrency in Java.
精彩评论