here's a little code I wrote. This next class waits for a connection and creates a new thread upon receiving one:
ServerSocket serverSocket = null;
ExecutorService serv = Executors.newCachedThreadPool();
serv.execute(new UserThread());
try {
serverSocket = new ServerSocket(FMDataManager.getPort());
serverSocket.setSoTimeout(0);
while (_listening){
System.out.println("Listening on port "+FMDataManager.getPort());
System.out.println("Waiting for connections.");
serv.execute(new UploadThread(serverSocket.accept()));
}
} catch (IOException e) {
System.err.println("Could not listen on port: "+FMDataManager.getPort()+".");
System.exit(-1);
}
as you can see i am using ServerSocket.accept() method to wait for a connection.
The thread is indeed created, but it won't run. I put a little "thread created" in its constructor and another message "starting thread" in run(), but I only got the first message. After that it didn't do anything, I didn't even get "thread created".
Any ideas please?
I've add the implementation of the UploadThread I am trying to start, maybe It'll help
public class UploadThread extends Thread{
Socket _socket;
public UploadThread(Socket socket) {
super("UserThread");
_socket = socket;
}
public void run(Socket socket) {
System.out.println("entred upload thread");
DataOutputStream out = null;
DataInputStream in = null;
try {
out = new DataOutputStream(_socket.getOutputStream());
in = new DataInputStream(_socket.getInputStream());
FileMessage inputMessage;
SendFile outputMessage;
inputMessage = (FileMessage) CommandEnum.readMessage(in);
System.out.println("F: "+inputMessage.getCaption());
File file = null;
Iterator<File> itr = FMDataManager.getFiles().iterator();
while (itr.hasNext()){
File temp = itr.next();
if (temp.getName().equals(inputMessage.getFile()))
file = temp;
}
outputMessage = new SendFile(file);
outputMessage.send(out);
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
_socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Try serv.submit instead of serv.execute.
EDIT
Looks like UploadThread isn't overriding run() correctly. That being said, your run method declaration should look like this:
#Override
public void run(){
//do stuff
}
There's no need to pass socket as an argument.
As indicated by sthupahsmaht's comment your UploadThread implementation is wrong. The signature for the run() method is public void run(). Currently you are creating a new method with the signature public void run(Socket). As run() doesn't take any arguments you have to pass all parameters via the constructor or setters.
There are two best practices that can help you avoid such mistakes in the future:
Whenever you implement or override a method, annotate it with #Override. If you create a new method with #Override, the compiler signals an error.
Don't extend Thread but implement Runnable. Thread has a default implementation for run() which does nothing. This is what happens with your code currently.
Without seeing the part of the code that actually constructs the thread, I'll guess you're NOT calling the 'start()' method on the thread object.
Needs to be something like this:
Thread thr = new Thread(new Runnable() { void run() { /* do stuff */ }) ;
thr.start() // GO!
Related
I am writing a Java client/server GUI application using sockets and here is the problem:
I have a button to start listening for a specified port:
button actionPerformed method
private void listenButtonActionPerformed(java.awt.event.ActionEvent evt) {
int port = Integer.parseInt(portTextfield.getText(), 10);
try {
socket.listen(port);
} catch (IOException ex) {
}
}
Here is the socket.listen method
public static void listen() throws IOException {
ServerSocket ss = new ServerSocket(port);
while (true)
new socket(ss.accept());
}
"socket" class extends "Thread"
So after ss.accept() returns a value it creates new socket instance in separate thread.
After clicking the button the GUI freezes because inside the socket.listen method there is an infinite loop. How can I avoid that?
You have two pitfalls in your design:
ss.accept() is a blocking call so your UI will freeze until there is an incoming connection
Never run while(true) loops in the EDT.
Instead do the following:
When the button is clicked create a thread that will start listening for incoming connections.
Whenever you have an incoming connection, create another thread that will take the incoming client connection and deal with it.
as long as your
new socket(ss.accept());
returns immediately, you only need to change your
while (true)
this puts the EDT (Event Dispatch Thread) into an infinite loop and your GUI becomes irresponsive. So, delete this line.
If you can't then use the SwingWorker class ( http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List)
Create a nested class that extents SwingWorker. Just call a swingWoker.execute(); (after you have created its object) in your listenButtonActionPerformed(java.awt.event.ActionEvent evt) method.
See the tutorial: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Never create a new thread and run it from from the Swing EDT
Check this out: http://javarevisited.blogspot.ro/2012/02/what-is-blocking-methods-in-java-and.html
1) If you are writing GUI application may be in Swing never call
blocking method in Event dispatcher thread or in the event handler.
for example if you are reading a file or opening a network connection
when a button is clicked don't do that on actionPerformed() method,
instead just create another worker thread to do that job and return
from actionPerformed(). this will keep your GUI responsive, but again
it depends upon design if the operation is something which requires
user to wait than consider using invokeAndWait() for synchronous
update.
Using multiple threads: http://javarevisited.blogspot.ro/2011/02/how-to-implement-thread-in-java.html
You will need to use Multi-Threading. If I where you, I would separate the GUI code and the server code and when the button is pressed, I simply launch the Server code as a new Thread.
Your code is freezing the GUI basically because all events are executed on the Event Dispatcher Thread (EDT) which is the thread which takes care of all your GUI stuff and respective events. If you either block it, stop it or throw in loops it will affect on its performance.
Try these...
1. During getting the initial connection delay can occur, so first create and empty socket,then try to connect to the server.
`Socket s = new Socket();`
`s.connect(new InetSocketAddress("ip_addr",port_nos),1000);`
2. And Secondly always keep the Non-UI work out of Your UI thread..
Here is my Example of Server - Client Communication..
Client side code:
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket();
s.connect(new InetSocketAddress("127.0.0.1", 4444),1000);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Server side code:
import java.io.*
import java.net.*;
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
#Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}
I am writing a Java client/server GUI application using sockets and here is the problem:
I have a button to start listening for a specified port:
button actionPerformed method
private void listenButtonActionPerformed(java.awt.event.ActionEvent evt) {
int port = Integer.parseInt(portTextfield.getText(), 10);
try {
socket.listen(port);
} catch (IOException ex) {
}
}
Here is the socket.listen method
public static void listen() throws IOException {
ServerSocket ss = new ServerSocket(port);
while (true)
new socket(ss.accept());
}
"socket" class extends "Thread"
So after ss.accept() returns a value it creates new socket instance in separate thread.
After clicking the button the GUI freezes because inside the socket.listen method there is an infinite loop. How can I avoid that?
You have two pitfalls in your design:
ss.accept() is a blocking call so your UI will freeze until there is an incoming connection
Never run while(true) loops in the EDT.
Instead do the following:
When the button is clicked create a thread that will start listening for incoming connections.
Whenever you have an incoming connection, create another thread that will take the incoming client connection and deal with it.
as long as your
new socket(ss.accept());
returns immediately, you only need to change your
while (true)
this puts the EDT (Event Dispatch Thread) into an infinite loop and your GUI becomes irresponsive. So, delete this line.
If you can't then use the SwingWorker class ( http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List)
Create a nested class that extents SwingWorker. Just call a swingWoker.execute(); (after you have created its object) in your listenButtonActionPerformed(java.awt.event.ActionEvent evt) method.
See the tutorial: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Never create a new thread and run it from from the Swing EDT
Check this out: http://javarevisited.blogspot.ro/2012/02/what-is-blocking-methods-in-java-and.html
1) If you are writing GUI application may be in Swing never call
blocking method in Event dispatcher thread or in the event handler.
for example if you are reading a file or opening a network connection
when a button is clicked don't do that on actionPerformed() method,
instead just create another worker thread to do that job and return
from actionPerformed(). this will keep your GUI responsive, but again
it depends upon design if the operation is something which requires
user to wait than consider using invokeAndWait() for synchronous
update.
Using multiple threads: http://javarevisited.blogspot.ro/2011/02/how-to-implement-thread-in-java.html
You will need to use Multi-Threading. If I where you, I would separate the GUI code and the server code and when the button is pressed, I simply launch the Server code as a new Thread.
Your code is freezing the GUI basically because all events are executed on the Event Dispatcher Thread (EDT) which is the thread which takes care of all your GUI stuff and respective events. If you either block it, stop it or throw in loops it will affect on its performance.
Try these...
1. During getting the initial connection delay can occur, so first create and empty socket,then try to connect to the server.
`Socket s = new Socket();`
`s.connect(new InetSocketAddress("ip_addr",port_nos),1000);`
2. And Secondly always keep the Non-UI work out of Your UI thread..
Here is my Example of Server - Client Communication..
Client side code:
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket();
s.connect(new InetSocketAddress("127.0.0.1", 4444),1000);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Server side code:
import java.io.*
import java.net.*;
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
#Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}
I am writing a Java client/server GUI application using sockets and here is the problem:
I have a button to start listening for a specified port:
button actionPerformed method
private void listenButtonActionPerformed(java.awt.event.ActionEvent evt) {
int port = Integer.parseInt(portTextfield.getText(), 10);
try {
socket.listen(port);
} catch (IOException ex) {
}
}
Here is the socket.listen method
public static void listen() throws IOException {
ServerSocket ss = new ServerSocket(port);
while (true)
new socket(ss.accept());
}
"socket" class extends "Thread"
So after ss.accept() returns a value it creates new socket instance in separate thread.
After clicking the button the GUI freezes because inside the socket.listen method there is an infinite loop. How can I avoid that?
You have two pitfalls in your design:
ss.accept() is a blocking call so your UI will freeze until there is an incoming connection
Never run while(true) loops in the EDT.
Instead do the following:
When the button is clicked create a thread that will start listening for incoming connections.
Whenever you have an incoming connection, create another thread that will take the incoming client connection and deal with it.
as long as your
new socket(ss.accept());
returns immediately, you only need to change your
while (true)
this puts the EDT (Event Dispatch Thread) into an infinite loop and your GUI becomes irresponsive. So, delete this line.
If you can't then use the SwingWorker class ( http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List)
Create a nested class that extents SwingWorker. Just call a swingWoker.execute(); (after you have created its object) in your listenButtonActionPerformed(java.awt.event.ActionEvent evt) method.
See the tutorial: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Never create a new thread and run it from from the Swing EDT
Check this out: http://javarevisited.blogspot.ro/2012/02/what-is-blocking-methods-in-java-and.html
1) If you are writing GUI application may be in Swing never call
blocking method in Event dispatcher thread or in the event handler.
for example if you are reading a file or opening a network connection
when a button is clicked don't do that on actionPerformed() method,
instead just create another worker thread to do that job and return
from actionPerformed(). this will keep your GUI responsive, but again
it depends upon design if the operation is something which requires
user to wait than consider using invokeAndWait() for synchronous
update.
Using multiple threads: http://javarevisited.blogspot.ro/2011/02/how-to-implement-thread-in-java.html
You will need to use Multi-Threading. If I where you, I would separate the GUI code and the server code and when the button is pressed, I simply launch the Server code as a new Thread.
Your code is freezing the GUI basically because all events are executed on the Event Dispatcher Thread (EDT) which is the thread which takes care of all your GUI stuff and respective events. If you either block it, stop it or throw in loops it will affect on its performance.
Try these...
1. During getting the initial connection delay can occur, so first create and empty socket,then try to connect to the server.
`Socket s = new Socket();`
`s.connect(new InetSocketAddress("ip_addr",port_nos),1000);`
2. And Secondly always keep the Non-UI work out of Your UI thread..
Here is my Example of Server - Client Communication..
Client side code:
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket();
s.connect(new InetSocketAddress("127.0.0.1", 4444),1000);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Server side code:
import java.io.*
import java.net.*;
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
#Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}
I am using this code in a application for sending some string throw a socket.
public class OutgoingData {
public static DataOutputStream dos = null;
public static String toSend = "";
public static volatile boolean continuousSending = true;
public static String toSendTemp = "";
public static void startSending(final DataOutputStream d) {
new Thread(new Runnable() {
public void run() {
try {
dos = d;
while (continuousSending) {
if (!toSend.equals(toSendTemp)) {
dos.writeUTF(toSend);
dos.flush();
toSendTemp = toSend;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
And from another thread I am calling this method
private void send(String str) {
OutgoingData.toSend = str;
}
Are there any problems that could appear using this implementation? Excepting the case when send() is called synchronously from two threads.
I am not using something like this:
private void send(final String str){
new Thread(new Runnable() {
#Override
public void run() {
synchronized (OutgoingData.dos) {
try {
OutgoingData.dos.writeUTF(str);
OutgoingData.dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
Because the system on which this code is runned, has a limit on the number of threads a process can create and takes a long time to get a lock on an object.
Your implementation is not thread safe:
if (!toSend.equals(toSendTemp)) {
// toSend can be changed before this line happens
// causing you to miss data
dos.writeUTF(toSend);
dos.flush();
// or here
toSendTemp = toSend;
}
You need some form of thread synchronization, regardless of whether or not it is "slow".
A better choice rather than busy waiting on a field is to use a BlockingQueue<String> This will ensure you never miss a value, nor do you consume CPU when there is nothing to do.
A good way of wrapping up a Queue and a Thread (pool) is to use an ExecutorService which does both.
In your case, a Socket stream is a queue already so queuing writing to another queue is likely to be redundant and all you really need to buffer your output stream.
Because the system on which this code is runned, has a limit on the number of threads a process can create and takes a long time to get a lock on an object.
Creating a thread is more than 100x than creating a thread. Ideally you don't want to have either. Note: the Socket already has a write lock.
I'm trying to do something potentially stupid, but I reckon it's a good idea, so bear with me. I tried to implement it, but I hit an awkward issue with sockets closing between threads - so I want some fresh eyes on the case.
Scenario
I want to write an object from a Client to a Server via sockets. There may be more than one Client communicating with the Server concurrently.
The object, a Message, is handled by the Server through its handling mechanisms. It is proposed that instead of the Server's main thread looking out for new incoming connections, a Listener thread is set up. Once it spots an incoming connection, it alerts the Server, storing the socket in a queue without receiving the data, so it can go back to listening quickly.
In its own time, the Server picks up the waiting socket, spawns a new thread, reads the Message, and closes the socket.
The code
Here's my first thoughts on how this should be implemented. There is a fundamental flaw in it which I will explain below.
Ignore the use of public fields - I'm just trying to make the code short for you guys
public class Server {
public boolean messageWaiting = false;
public static void main(String[] args) {
new Server().run();
}
public void run() {
Listener l = new Listener();
l.listen(this);
try {
while (true) {
System.out.println("I'm happily doing my business!");
Thread.sleep(1000);
if (messageWaiting) {
acceptMessages(l);
}
}
} catch (InterruptedException die) {}
}
private void acceptMessages(Listener l) {
while (!l.waiting.isEmpty()) {
try (
Socket client = l.waiting.poll();
ObjectInputStream ois = new ObjectInputStream(client.getInputStream())
) {
// Handle messages in new threads! (or a thread pool)
new Thread() {
public void run() {
try {
System.out.println(ois.readObject());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}.start();
} catch (Exception ex) {
// Oh no! The socket has already been closed!
ex.printStackTrace();
}
}
}
}
public class Listener {
public ConcurrentLinkedQueue<Socket> waiting = new ConcurrentLinkedQueue<>();
public void listen(final Server callback) {
new Thread() {
public void run() {
try (ServerSocket rxSock = new ServerSocket(7500)) {
while (!isInterrupted()) {
try (Socket client = rxSock.accept()) {
// Once a new socket arrives, add it to the waiting queue
waiting.add(client);
// Alert the server
callback.messageWaiting = true;
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}.start();
}
}
public class Client {
public static void main(String[] args) {
try (
Socket txSock = new Socket(InetAddress.getLoopbackAddress(), 7500);
ObjectOutputStream oos = new ObjectOutputStream(txSock.getOutputStream())
) {
oos.writeObject("This is a Message, trust me.");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
What's wrong with this?
This:
I'm happily doing my business!
I'm happily doing my business!
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Unknown Source)
at Server.acceptMessages(Server.java:30)
at Server.run(Server.java:20)
at Server.main(Server.java:9)
This is because the Java 7 try blocks I'm using close the sockets once they're finished. So why don't I do this manually? Try yourself - you end up with a warning saying you're only ever going to call close() on a null object!
So, how do I avoid the whole issue of my incoming socket being closed before the Server thread picks up on it? Or is this a bad idea anyway and I should do something else?
Your statement in Listener
try (Socket client = rxSock.accept()) { ...
Is a try-with-resources for the client socket. As soon as you add it to the queue and exit the try block, the socket gets auto-closed.