I've coded a client program that communicates with my arduino server. It had a swing button and a methog that ran a loop checking for any input from the server. I tried it with multiple instances running from different or/and the same IP and everything was fine. Now I tried implementing that same method for the socket in a app with JavaFX GUI. After I read here and there that it needs to be on a separate thread I did it as instructed and it seems to be working just fine. If I try to launch a second instance of it though,it imidiately throws NullPointerException on the line where i check socket.isConnected() && !Socket.isClosed(). The first instance continues to work just fine, but the other one just stays with the GUI open.
As I've done it with the same class but not on a new thread and with swing button, I can say that the problem is not on the server side.
I need to be able to launch as many instances of the program as I want while they all keep an open socket at all times. Any ideas on how to fix that ?
Update: I tryed recalling the initiation in the loop when socket is lost. It seems that the socket closes right after it is opened.
Here is the Class for the client:
package panelSouth;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class Networking implements Runnable{
static Socket socket;
static OutputStreamWriter out;
public void run() {
//Initializing socket - IP/PORT
String host = "192.168.1.178";
int port = 2015;
boolean connected=true;
do{
try{
socket = new Socket(host,port);
}
catch(Exception unknownHostException){
connected=false;
System.out.println("Connecting to host...");
}
}while(connected==true);
System.out.println("Connection is a success!");
System.out.println("Requesting pin states...");
//Requesting pin states on startup.
try{
out = new OutputStreamWriter(socket.getOutputStream());
out.write("r;");
out.flush();
}catch(Exception ex){
System.out.println(ex);
}
listen();
}
//Listening for incoming commands from host
public static void listen(){
try{
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream() ) );
while(socket.isConnected() && !socket.isClosed()){
States.commandProcess(in.readLine());
}
}catch(Exception ex){
System.out.println(ex);
}
}
//send commands.
static public void send(String command){
try{
out.write(command);
out.flush();
}catch(Exception ex){
System.out.println(ex);
}
}
//closing the socket and resetting the pins on host on close up.
static public void close(){
try{
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
out.write("x;");
out.flush();
socket.close();
}catch(Exception exception){
}
}
}
And here is the Main:
public static void main(String[] args) throws Exception{
Thread network = new Thread(new Networking());
network.setDaemon(true);
network.start();
launch(args);
}
I removed the loops in the defining of the socket and I put recall of the function only in the catch{} part. It seems that the loop was defining more than one socket or something and when I was actually sending data to the socket, it was another socket. Also I changed the thread handling and made it with Task which seems to work a lot better with JavaFX scene.
Related
I'm trying to make a chat system project (still incomplete) using java, but I need small help in forwarding the client's received message.
The server is working as multi-threading so many clients can connect to it, what I want is: (Assumed scenario) if 6 clients are connected to the server, then one of them send a message, it should be forwarded to all connected clients through the server.
here is the 2 codes..
Server side
import java.io.*;
import java.net.*;
public class ChatServer implements Runnable
{
Socket csocket;
ChatServer(Socket csocket){ this.csocket = csocket; }
public static void main(String[]args)throws Exception
{
ServerSocket sersock=new ServerSocket(3000);
System.out.println("Server ready for chatting");
while(true)
{
Socket sock =sersock.accept();
new Thread(new ChatServer(sock)).start();}
}
public void run()
{
try{
System.out.println(Thread.currentThread().getName() + ": HELLO");
BufferedReader keyRead=new BufferedReader(new InputStreamReader(System.in));
OutputStream ostream=csocket.getOutputStream();
PrintWriter pwrite=new PrintWriter(ostream, true);
InputStream istream=csocket.getInputStream();
BufferedReader receiveRead=new BufferedReader(new InputStreamReader(istream));
String receiveMessage, sendMessage;
while(true) {
if((receiveMessage=receiveRead.readLine())!=null)
{
System.out.print(Thread.currentThread().getName() + ": ");
if(receiveMessage.equals("QUIT"))
Thread.currentThread().stop();
else
System.out.println(receiveMessage);}
sendMessage=keyRead.readLine();
pwrite.println(sendMessage);
System.out.flush();}
} catch (IOException e){ System.out.println(e); }
}
}
client side
import java.io.*;
import java.net.*;
public class ChatClient
{
public static void main(String[]args)throws Exception
{
Socket sock =new Socket("localhost", 3000);
// reading from keyboard (keyRead object)
BufferedReader keyRead=new BufferedReader(new InputStreamReader(System.in));
// sending to client (pwrite object)
OutputStream ostream=sock.getOutputStream();
PrintWriter pwrite=new PrintWriter(ostream, true);
// receiving from server ( receiveRead object)
InputStream istream=sock.getInputStream();
BufferedReader receiveRead=new BufferedReader(new InputStreamReader(istream));
System.out.println("Start the chitchat, type and press Enter key");
String receiveMessage, sendMessage;
while(true)
{
sendMessage=keyRead.readLine();// keyboard reading
pwrite.println(sendMessage);// sending to server
System.out.flush();// flush the data
if((receiveMessage=receiveRead.readLine())!=null)//receive from server
{
System.out.println(receiveMessage);// displaying at DOS prompt
}
}
}
}
Thanks in advance.
I write these types of server applications frequently, as a way of connection client through a relay server when direct connections between them are not possible. The solution is simple, put each socket that you receive from the accept() function into a List or Tree of your choice.
List<Socket> connectionList = new ArrayList<Socket>();
...
Socket sock =sersock.accept();
connectionList.add(sock);
...
for (Socket connection : connectionList) {
connection.getOutputStream().write(msgBytes);
}
I have the UWP app("server") running on win10 prof, this UWP app is an application service and I have another UWP app(Client), which communicates with that service using TSP/IP. How many clients running on the other win10 devices can connect to the "server" at the same time?
Using the StreamSocketListener class, I believe you can handle an unlimited number of client socket connections (depending on implementation, hardware, bandwidth, etc.). Here's a basic example of the server-side implementation of the listener using a static class.
// Define static class here.
public static StreamSocketListener Listener { get; set; }
// This is the static method used to start listening for connections.
public static async Task<bool> StartServer()
{
Listener = new StreamSocketListener();
// Removes binding first in case it was already bound previously.
Listener.ConnectionReceived -= Listener_ConnectionReceived;
Listener.ConnectionReceived += Listener_ConnectionReceived;
try
{
await Listener.BindServiceNameAsync(VMS.Current.Port);
return true;
}
catch (Exception ex)
{
Listener.ConnectionReceived -= Listener_ConnectionReceived;
Listener.Dispose();
return false;
}
}
private static async void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
var remoteAddress = args.Socket.Information.RemoteAddress.ToString();
var reader = new DataReader(args.Socket.InputStream);
var writer = new DataWriter(args.Socket.OutputStream);
try
{
// Handle communication here. You'll likely use an infinite loop of reading from the input stream until the socket is disconnected.
}
catch (Exception ex)
{
writer.DetachStream();
reader.DetachStream();
return;
}
}
There are different ways of handling stream sockets once you have both ends connected, and I had to do some research and experimentation to find a process that worked for what I was doing.
OK, so I'm a bit new to SwingWorker in Java.
I've built a Java GUI that, when the "Start" button is pressed, launches several SwingWorker threads. The first thread simply keeps track of run time and updates the GUI appropriately. The second one plays a series of sounds files. The third (and problematic) thread should monitor the serial port for incoming data to be manipulated later on down the road. All of these threads will be running for a while, hence them being SwingWorkers.
I am using the jSSC library (https://code.google.com/p/java-simple-serial-connector/wiki/jSSC_examples) to read data from the serial port, and it does so by firing an eventListener.
My question: Is it redundant/inelegant to code an EventListener inside of a SwingWorker thread? And if so, is there a better way to go about this?
Here is a bit of my code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
SerialPort serialPort = findPort(); // returns a serialport I can use to read data from.
SwingWorker worker1 = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
long elapsedTime, startTime = System.currentTimeMillis();
while (true){
Thread.sleep(1000);
elapsedTime = (System.currentTimeMillis() - startTime)/1000;
jTimeField.setText(String.format("%02d:%02d:%02d", elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60));
if (isCancelled()){} /* Check if thread has been canceled */
}
}
};
SwingWorker worker2 = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
// This Thread: Plays music files; Self terminates; On termination also terminates worker 1 and 3 via cancel().
}
};
SwingWorker worker3 = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
serialPort.addEventListener(new SerialPortReader());
return null;
}
class SerialPortReader implements SerialPortEventListener {
#Override
public void serialEvent(SerialPortEvent event) {
byte buffer[];
if (event.isRXCHAR() && event.getEventValue() > 0){
buffer = serialPort.readBytes();
for (byte b: buffer){
// Do stuff with incoming data
}
}
}
}
};
}
Any and all constructive criticism is appreciated.
It does not do any good to add the event listener in your swingworker thread and then return once that's done. Why not just add the listener from your EDT and, if it takes long to process events, fire off processing threads from there? Listening to events can't be blocking, that would defeat the entire Observer pattern.
I am creating a j2me application which is interacting with a database on a server. Therefore I launch a thread to connect to the server. I handle all my command actions in a separate class which implements CommandListener.
When I try to get the response the server returned I get an empty String. I have tried waiting for the thread that connects to the server to return but this makes the application unresponsive.
Below is the code I am using.
//my network worker class.
public class NetworkConnector implements Runnable {
//constructor
public NetworkConnector(String url){
//url =>server url to connect to.
Thread thread = new Thread(this);
thread.start();
}
private String serverReply="";
private String url="
//method to connect to the server and return the
//response from the server.
public String sendData(String serverUrl) {
//open streams to connect to the Server.
httpConn = (HttpConnection)
Connector.open(serverUrl,Connector.READ_WRITE, true);
httpConn.setRequestMethod(HttpConnection.GET);
inStream = httpConn.openInputStream();
int read;
while ((read = inStream.read()) != -1) {
sb.append((char) read);
}
return sb.toString();
}
public String getServerReply() {
//serverReply is a class variable.
return serverReply;
}
public void run(){
//call the send method that connects to the server.
serverResponse = sendData(Url);
}
} //end of connector class.
// this class is where all my Command Actions are
//implemented.
public class CommandActionController implements
CommandListener, DataReceiver {
public void commandAction(Command cmd, Displayable d) {
//networkMgr => is the worker class that makes
//connection to the server.
networkMgr = new NetworkConnector("http://localhost
/JsonPhp/login.php?uname=" + loginUserInfo.userName +
"&passwd=" + loginUserInfo.password);
//here am getting the response from the server.
String serverResponse = networkMgr.getServerReply();
//at this point the ServerReponse String is Empty =>
//yet the server is supposed to return some String.
System.out.println("xxxxxxxxxxxxxxxxxx
ServerResponse =" + serverResponse);
}
}//end of CommandListener class.
Your expectations about serverResponse value are wrong; it can be empty at the moment when you attempt to obtain it in commandAction with the code snippet in the question.
In order to get non-empty value, you need to redesign method NetworkConnector.getServerReply() to make it properly wait until thread finishes and server response is indeed obtained.
If you do that, however, you will also have to redesign CommandActionController to keep user interface responsive - your testing with "waiting for the thread that connects to the server" has shown just that.
Redesigned code should just launch the server connect thread and exit the commandAction as soon as possible (possibly changing to some "wait screen" to let user see what happens). Next screen update should be triggered only after server response is obtained.
Consider studying a tutorial specifically targeted on explaining how to properly design this kind applications - Networking, User Experience, and Threads:
This article explains how your MIDlet can make network connections without compromising your user interface. It includes six iterative examples that illustrate multithreaded networking and the use of a wait screen...
Here is how I'd do without java.util.concurrent:
Result handleRequest(){
final String url = // get url
Work work = new Work(url):
Thread t = new Thread(work);
t.start();
// do other stuff
if(t.isAlive()){
// still running
}
// this waits until the work is done
// and it will be safe to access work.result after
// this call has returned.
t.join();
return work.result;
}
and then
class Work implements Runnable{
final String url;
Result result;
public void run(){
this.result = // do your network stuff
}
}
You shouldn't start a thread in the constructor. Also, runnable are meant to be passed to threads. The easiest (and the "proper") way of doing this would be as follows:
Implement a Callable instead of a Runnable.
Use a ExecutorService instead of a Thread
Use Future object to do the processing asynchronously/be responsive to user
Here is a simple example.
class Stuff {
final ExecutorService exec =
Executors.newCachedExecutorService(// please see doc);
Result process(String url){
Future<Result> future = exec.submit(new Work(url));
// do some other stuff
if(future.isDone()){
// return result?
}
return future.get(); // this call will wait until result is available
}
}
and then
class Work implements Callable<Result> {
final String url;
Result call() throws Exception {
// do your network stuff here
return result;
}
}
See documentation of java.util.concurrent.ExecutorService.submit(), java.util.concurrent.Future and java.util.concurrent.Callable for details.
I am developping a BlackBerry application which communicates with the server via HTTP requests(javax.microedition.io.HttpConnection). On device, user clicks some UI items, and device sends the requests to server, when the response comes, UI changes. Communication takes place under new thread, while UI thread pushes and pops ProgressDialogScreen.
The problem is sometimes, when response comes and ProgressDialogScreen is popped, UI does not change but after couple seconds UI changes. If you have requested in between when ProgressDialogScreen is popped and when new Screen is pushed, there comes the mess. First oldest new Screen is pushed, and the newest new Screen is pushed. And this situation can be observed like server responsing wrong requests. This problems occur on simulator and device.
The other problem is, sometimes two same response returns for one request. I was able to see these two problems on simulator at the logs, but i have not able to see this issue on device since i can not see the logs.
EDIT:
String utf8Response;
HttpConnection httpConn = null;
try{
httpConn = (HttpConnection) Connector.open(url);
httpConn.setRequestMethod(HttpConnection.GET);
httpConn.setRequestProperty("Content-Type", "text/html; charset=UTF8");
if(sessionIdCookie != null){
//may throw IOException, if the connection is in the connected state.
httpConn.setRequestProperty("Cookie", sessionIdCookie);
}
}catch (Exception e) {
//...
}
try{
httpConn.getResponseCode();
return httpConn;
}catch (IOException e) {
// ...
}
byte[] responseStr = new byte[(int)httpConn.getLength()];
DataInputStream strm = httpConn.openDataInputStream();
strm.readFully(responseStr);
try{
strm.close();
}catch (IOException e) {
// ....
}
utf8Response = new String(responseStr, "UTF-8");
If this code successfully run, this piece of code runs and new screen is pushed:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS);
if (accounts.size() == 0){
DialogBox.inform(Account.NO_DEPOSIT);
return;
}
currentScreen = new AccountListScreen(accounts);
changeScreen(null,currentScreen);
}
});
public void changeScreen(final AbstractScreen currentScreen,final AbstractScreen nextScreen) {
if (currentScreen != null)
UiApplication.getUiApplication().popScreen(currentScreen);
if (nextScreen != null)
UiApplication.getUiApplication().pushScreen(nextScreen);
}
EDITv2:
private static void progress(final Stoppable runThis, String text,boolean cancelable) {
progress = new ProgressBar(runThis, text,cancelable);
Thread threadToRun = new Thread() {
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
try{
UiApplication.getUiApplication().pushScreen(progress);
}catch(Exception e){
Logger.log(e);
}
}
});
try {
runThis.run();
} catch (Throwable t) {
t.printStackTrace();
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
try {
UiApplication.getUiApplication().popScreen(progress);
} catch (Exception e) { }
}
});
}
};
threadToRun.start();
}
By the way ProgressBar is extended from net.rim.device.api.ui.container.PopupScreen and Stoppable is extended from Runnable
I preferred to pop progress bar after new Screen is prepared and pushed. This way there will be no new request between request and response.
Why not do:
private static void progress(final Stoppable runThis, String text,boolean cancelable) {
progress = new ProgressBar(runThis, text,cancelable);
UiApplication.getUiApplication().pushScreen(progress);
[...]
Seems like you are parsing on the UI Thread. Please remove Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS); from ui thread and do it in a separate thread.