I'm writing a thread code that opens a server socket and that when reached by a connection asks the user to choose a directory.
I've tried using the InvokeLater() and it works, but i have no control on when to retrieve the selected file directory, so InvokeAndWait looked like the right alternative. Except it doesn't actually do anything, i've even tried givin it a println and it simply does not seem to execute anything.
How do i fix it? I'm running out of ideas.
Thanks!
public class FileTransfListener implements Runnable {
protected JFileChooser dirChooser;
public FileTransfListener(JFileChooser f){
dirChooser=f;
}
#Override
public void run() {
ServerSocket serverSocket = null;
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
try {
serverSocket = new ServerSocket(60905);
} catch (IOException e1) {
return;
}
while(true){
try {
socket = serverSocket.accept();
String dir=null;
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
dirChooser.showOpenDialog(null);
}
});
try{
dir= dirChooser.getSelectedFile().getAbsolutePath();
}
catch(NullPointerException e){
dir=null;
}
System.out.println(dir);
}
catch (IOException ex) {
ex.printStackTrace();
try {
serverSocket.close();
}
catch (IOException e) {
e.printStackTrace();
}
} catch (InvocationTargetException |InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
Its a deadlock
dirChooser.showOpenDialog(null); is a blocking method and you should use it directly not trough SwingUtilities
What happens here is:
SwingUtilities.invokeAndWait submits task to EDT - blocks until it is completed
dirChooser.showOpenDialog(null); schedules dialog draw to EDT - awaits unitl dialog is closed - but its never drawn....
Since invokaAndWait awaits for completion on EDT - event queue is not emptied and task awaits for itself to complete - deadlock
What you should do is to call directly without EDT queue.
Documentation has simple exmaple of this:
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(parent);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " +
chooser.getSelectedFile().getName());
}
Related
I have a classic server-multi-clients program. Tthe server listens to ServerSocket and for each incoming socket it builds a new Runnable class and executes it in ExecuteService.
In the run method of the Runnable class, I open try-with-resources block and in the try I have a while loop that reads from inputstream and writes to outputstream until it receives FIN command from the clients. Everything works fine and the clients disconnect successfully. The run reaches the finally block and prints some stuff for testing, but it doesn't exit the try block so it does not exit the run method and I am stuck in the run somewhere, maybe the read method of the inputstream.
I can post the code if anyone interested.
How can I force close everything in the finally and exit the run method?
The code:
Server.java:
public static void main(String[] args) {
playersReady = new ArrayList<Integer>();
ServerSocket server = null;
try {
server = new ServerSocket(Consts.PORT);
ExecutorService service = Executors.newFixedThreadPool(characters.size());
while(playersReady.size()<characters.size()){
RequestHandler handler = new RequestHandler(server.accept());
service.execute(handler);
}
service.shutdownNow();
service.shutdown();
while(!service.isTerminated()){}
System.out.println("finished");
RequestHandler.java
public final class RequestHandler implements Runnable {
.....
public void run() {
//DataOutputStream output = null;
//DataInputStream input = null;
try (DataOutputStream output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream())){
// socket.setSoTimeout(500);
handleReady(input.readUTF().split(" "), output);
while (/*!shutdown && !socket.isClosed() && */socket.isConnected()) {
System.out.println("check before read " + character.getId());
String request = input.readUTF();
System.out.println("check after read " + character.getId());
System.out.println("-----------------------------------" + request);
if (shutdown) {
socket.shutdownInput();
socket.getOutputStream().flush();
socket.shutdownOutput();
break;
}
String[] requestParser = request.split(" ");
if (requestParser[1].equals("DMG")) {
// handle damage request
handleDamage(requestParser, output);
} else if (requestParser[1].equals("BND")) {
// handle bandage request
handleBandage(requestParser, output);
} else if (requestParser[1].equals("FIN")) {
// handle finish request
handleFin();
if (!socket.isClosed())
socket.shutdownInput();
if (!socket.isClosed()) {
socket.getOutputStream().flush();
socket.shutdownOutput();
}
shutdown = true;
break;
} else {
break;
}
}
} catch (SocketTimeoutException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
shutdown = true;
break;
} catch (Throwable e) {
e.printStackTrace();
} finally {
try {
System.out.println("finished");
if (!socket.isClosed())
socket.shutdownInput();
if (!socket.isClosed()) {
socket.getOutputStream().flush();
socket.shutdownOutput();
socket.close();
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("Done run");
}
....
The System.out.println("finished") in the finally is printed,
but the System.out.println("Done run") in the end of the run method does not!!
Why?
It stuck in the run method, I think in the readUTF call, but I closed all the resources!
You return before that line, that's why it is not run. The finally block is run anyway, because it is a finally block. Finally blocks are always run, there is only one exception from this rule: System.exit(), but this is not the case.
I have to build a chat program.
There is the server class, the client class and two threads to write and receive messages.
the two threads should run in an infinite loop and check all the time if there is an input and print that input afterwards.
But my program works for just one round. So the server and the client can write one single message, afterwards it stops and does not check for another message. Why does the thread not start again from the begin when it's never interrupted? --> see the code beneath
I hope you know what my problem is, it's quite hard for me to describe.
Thread to read a new Message
public class MsgWriter extends Thread {
private Socket s;
public MsgWriter(Socket s){
this.s = s;
}
public void run(){
int i = 0;
OutputStream out = null;
PrintWriter writer;
Scanner input;
while(!interrupted()){
try{
synchronized(s){
input = new Scanner (System.in);
out = s.getOutputStream();
writer = new PrintWriter(out);
String toserver = input.nextLine();
writer.write(toserver);
writer.flush();
System.out.println("me: " + toserver);
}
try {
Thread.sleep((int) (100 * Math.random()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch(Exception e) {
}
}
}
}
Thread to check if there is a new message and prints it.
public class MsgReader extends Thread {
Socket s;
public MsgReader(Socket s){
this.s = s;
}
public void run() {
int i = 0;
while (!interrupted()) {
try{
synchronized(s){
InputStream in = s.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String s = null;
while((s=reader.readLine()) != null){
System.out.println("d");
}
}
try {
Thread.sleep((int) (100 * 1));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch (Exception e){
}
}
}
}
The Server class starts a new server and waits for a client, afterwards it starts the two threads. The same with the client class, it connects to the server and starts the threads.
You're probably thowing an exception somewhere. In your catch blocks, print the error.
try {
} catch (Exception e) {
System.out.println("Error: " + e);
}
My first attempt at writing a client for a php socket server and I'm running into a little trouble and I'm sort of being flooded with info!
With the server, we want an open connection, I want my client end to wait until it receives data before notifying the thread to start parsing the input-stream. Is this achievable without using a loop? I'd rather be able to call lock.notify().
I was also looking at NIO, is this a viable option for what I want?
Here's the code I have so far, but again, I'm just trying to avoid the for(;;) and maybe even queue the received messages as they will most likely just be JSON
Thread serverRecieve = new Thread(new Runnable() {
#Override
public void run() {
try {
for (;;) {
if (in != null) {
String line;
while ((line = in.readLine()) != null) {
sout(line);
}
} else {
sout("inputstream is null! Waiting for a second to test again");
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(WebManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (IOException ex) {
Logger.getLogger(WebManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Thanks guys!
PS: I did look through A LOT of socket threads on here but decided it would be easier just to ask what I need.
I think you can use a while loop and put a condition using in != null as:
while(in == null){
//wait for a second before checking the in stream again
try {
sout("inputstream is null! Waiting for a second to test again");
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(WebManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
//now your in is available. Read the data and proceed
String line = null;
while ((line = in.readLine()) != null) {
sout(line);
}
The first while loop will terminate as soon in stream is available.
How about creating dedicated subtype of Runnable for reading from socket, like this:
class Reader implements Runnable {
private final Socket socket;
private volatile boolean stopped;
Reader(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
while (true) {
int in = socket.getInputStream().read();
// process in here
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (!stopped) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void stop() {
try {
stopped = true;
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client {
private volatile Reader reader;
void start() {
reader = new Reader(new Socket(serverHost, serverPort));
Thread readerThread = new Thread(reader, "Reader-thread");
readerThread.start();
}
void stop() {
Reader reader = this.reader;
// reader.stop() will close socket making `run()` method finish because of IOException
// reader.socket is final, thus we have proper visibility of it's values across threads
if (reader != null) reader.stop();
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java timer and socket problem
So here is the code.
What I want to do - is client loop with server, to get messages from server, which sends them sometimes.
Here is attempt with timer.
private MessageFrame mf;
private User us;
private Contact cn;
private Socket s;
private PrintStream ps;
private BufferedReader br;
private Timer timer ;
public MessageFrameListener(MessageFrame m_f, User u_s, Contact c_n){
timer = new Timer(500,new timerListener());
mf = m_f;
us = u_s;
cn = c_n;
m_f.addButtonListener(new SButtonListener());
m_f.addWinListener(new FrameListener());
}
public void init(){
try {
s = new Socket(InetAddress.getLocalHost(), 8072);
ps = new PrintStream(s.getOutputStream());
br = new BufferedReader( new InputStreamReader(s.getInputStream()));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timer.start();
}
public class timerListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
//String insert = mf.getInput();
String result;
try {
//проверить, что буфер не пуст
if((result = br.readLine()) != null){
String[] results = result.split(" ");
if("m".equals(results[0])){
if("-1".equals(results[2]))
mf.addLine2("Error");
else{
mf.addLine2(results[3]);
}
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
But when I run it - the program stops reacting to my actions.
I can't write a text, or press a button.
Read calls to BufferedReader are blocking, Run them in a separate thread preferably a swing worker. Your readLine() call is causing the main event thread to hang which means no other events are propagating.
To confirm this put a break in the TimerActionListener and investigate the running thread stack or just SIGQUIT and thread dump. It should be pretty clear what thread the read call is causing to block.
I believe your br.readline() call blocks until you get data from your InputStream. If nothing is coming over the socket to read, the code will just hang there.
You may want to see the thread over here: Asynchronous IO in Java?
I'm trying to make a program which listens to the client input stream by using socket programming and timer
but whenever timer executes..
it gets hanged
Please help me out
here is the code...
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
try
{
ServerUserName=jTextField1.getText();
ss=new ServerSocket(5000);
jButton1.enable(false);
jTextArea1.enable(true);
jTextField2.enable(true);
Timer t=new Timer(2000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
try
{
s=ss.accept();
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
jTextArea1.append(dis.readUTF());
}
catch(IOException IOE)
{
}
catch(Exception ex)
{
setLbl(ex.getMessage());
}
}
});
t.start();
}
catch(IOException IOE)
{
}
}
Thanks in advance
Make the program multi-threaded; one thread listens on the socket, the other one handles the GUI. Use SwingUtilities.invokeLater to let the GUI thread ("event dispatching thread") do the GUI updates whenever the network thread receives data.
Every call to accept waits for a new client to connect to the server. The call blocks until a connection is established. It sounds like you have a single client that maintains a connection to the server.
One solution is to pull
s=ss.accept();
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
outside of the timer portion of the code.
Update: Be aware though that readUTF is still going to block if there is no data available to be read.
I think you want to use socket timeouts instead of a timer:
Thread listener = new Thread() {
ServerSocket ss;
#Override
public void run() {
try {
ss = new ServerSocket(5000);
ss.setSoTimeout(2000);
try {
while (true) {
try {
final String text = acceptText();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jTextArea1.append(text);
}
});
} catch (final Exception ex) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setLbl(ex.getMessage());
}
});
}
}
} finally {
ss.close();
}
} catch (IOException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
private String acceptText() throws IOException {
Socket s = ss.accept();
try {
InputStream is=s.getInputStream();
try {
DataInputStream dis=new DataInputStream(is);
return dis.readUTF();
} finally {
is.close();
}
} finally {
s.close();
}
}
};
listener.setDaemon(true);
listener.start();