Java - Client giving error on connect - java

I am working on a simple Java messaging program. Before I begin working on more complex features, I would like to get the basic system working. Currently
Multiple clients can connect
Multiple clients can send messages that the server receives
Server closes connections when the client is terminates
This code in particular appears to be what is giving the errors. It is the run() method in my ClientThread.java thread (that implements runnable). This thread is for handling incoming messages from the server (sending messages works fine).
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class ClientThread implements Runnable{
private Socket server;
private DataInputStream in;
private DataOutputStream out;
public Text msgContent;
public void login(Stage stage, Scene main, String username, String password, String portString, String host) {
try {
int port = Integer.parseInt(portString);
this.server = new Socket(host, port);
this.in = new DataInputStream(server.getInputStream());
this.out = new DataOutputStream(server.getOutputStream());
stage.setScene(main);
Platform.runLater(new ClientThread());
}
catch (NumberFormatException e) {
System.out.println("Invalid Port");
return;
}
catch (IOException e) {
System.out.println("Error Connecting to Server");
return;
}
}
public void run() {
String msg = "";
try {
while (true) {
msg = in.readUTF(); //This line gives Errors
System.out.println("Read message from server");
msgContent.setText(msgContent.getText() + msg + "\n");
System.out.println("Added message from server to view");
}
}
catch(Exception ioe) {
ioe.printStackTrace();
System.out.println("Failed to read message from server and add to view.");
}
}
public void sendMsg(String msg) {
try {
out.writeUTF(msg);
} catch (Exception ioe) {
ioe.printStackTrace();
}
}
}
Note that msgContent is a Text object in my JavaFX frontend and in the inputStream from the server. My full code is here. The error I am getting is
java.lang.NullPointerException
at ClientThread.run(ClientThread.java:42)
at com.sun.javafx.application.PlatformImpl$6$1.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$6$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(Unknown Source)
at com.sun.glass.ui.win.WinApplication$4$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Failed to read message from server and add to view.
Also note that I am using Platform.runLater() to run this method. I want to know how to fix the above error so my code works. Thanks in advance.

Cause of NullPointer Exception
in is null.
Your NullPointerException occurs because in this call you create a new instance of the ClientManager class: Platform.runLater(new ClientThread());, so it won't use existing instance of ClientManager in which you have initialized the in and out members. Instead, you could use Platform.runLater(this);, to get rid of your NullPointerException.
However, your code has other issues...
Incorrect concurrent programming
You are hanging the JavaFX application thread which will stop your application from rendering or responding to UI input. Never busy wait the JavaFX application thread.
One way to accomplish what you are trying to do is to use the JavaFX concurrency utilities, in particular a Task.
Run the task on it's own thread, then it can loop, accepting input forever and it won't block your UI thread. You can (perhaps) make your thread a non-daemon thread so that it exits automatically when all of the other daemon threads complete. You could feed the input back to your UI using Platform.runLater. But, for the simple example you provided where you want to update some message text, instead you can invoke updateMessage (note this does not need a Platform.runLater call as the Task class takes care of that kind of detail for you). To get your message label updated, you can bind it's text property to the task's message property. There are examples of how to do this in the Task javadoc.

Related

Continuous running java socket server thread exit on second run

I have a java socket client application that send data through TCP over Socket. The data it send is byte array and can send inconsistent data within inconsistent time interval. Although data send at a particular time will be complete in itself and will not have any marker for end of message. Code for client cannot be modified. I had to create a running thread for server so that it will read data whenever it is available on socket.Server application work as - Another class create server socket and start thread for incoming message. Incoming message thread read for message on socket passed while initializing the thread.
The code has following issues.1) It reads only the first data sent from client and thread exits on attempting to read second run2) Cannot use thread to wait for some time period as data can be sent from client in any time interval3) Cannot try opening and closing socket as another thread on server application will send data to client at any time interval.4) Do not want code that will block execution of complete application as another thread of this application will be sending data to client through same socket.
Please help and let me know for any further information. Code as below :
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class IncomingMsg extends Thread {
InputStream in =null;
private Socket clientSocket =null;
public IncomingMsg(Socket clientSoc){
this.start();
clientSocket = clientSoc;
}
public void run(){
try {
in = clientSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
byte[] data = new byte[100];
int count = in.read(data); //this is where thread exits on second run as new message may not have been received by the time execution reaches this point.
String message = "";
if(count>0)
{
for(int num=0;num<count;num++)
{message = message + " "+ data[num];}
System.out.println("Received Message from IP:"+clientSocket.getInetAddress()+" Message Byte:" +message);
}
data=null;
} catch (Exception e) {
logger.error(this.getClass().getName()+ ": Exception in receiving message "+ e);
}}} }
There was no issue with the given code. Problem was client application changes local port if it does not receive any message. Since server application is not sending any message, local port of client increment and thus server cannot read data on the second run. Will update answer more if any further clue is received.

Java Sockets: One Server and Multiple Clients

So I created a basic client-server program in java. It starts out like this:
Client connects to Server
Server asks for Client's name
Client responds with name
Server greets Client
After this, Client speaks and the Server repeats the words back
I got this to work without too much trouble using this tutorial. The problem comes whenever I try to introduce multiple clients. I thought that it would work because I'm using multiple threads, however, the second clients just hangs until the first client quits and then it starts it work (the server does accept input from the second client, but it doesn't respond with anything until the first client quits).
Here is the code I'm using:
import java.net.*;
import java.io.*;
public class Server extends Thread {
private ServerSocket listener;
public Server(int port) throws IOException {
listener = new ServerSocket(port);
}
public void run() {
while(true) {
try {
Socket server = listener.accept();
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("What is your name?");
DataInputStream in = new DataInputStream(server.getInputStream());
String user_name = in.readUTF();
out.writeUTF("Hello "+user_name);
while(true) {
String client_message = in.readUTF();
out.writeUTF(client_message);
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int port = 6006;
try {
Thread t = new Server(port);
t.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Can someone explain what I'm doing wrong?
I have looked at the using Runnable instead of Extends Thread, but I ran into even more problems there, so I want to try and work with this first.
Incoming connections are only handled by the line listener.accept();. But after you got a client connected, you're stuck in the while loop. You need to create a new Thread (or Runnable executed on an ExecutorService if you expect high load), and start it, then immediately accept the next connection.
In a nutshell, this is what is going wrong.
You are using exactly ONE thread as the server.
Blocking this thread when you call listener.accept()
This is what you need to do:
Create two classes
1: Server - Similar to what you have now, but instead of doing the actual work of acting as an echo server, it just spawns a new Thread which starts listening on a NEW PORT (which you can select randomly), and sends the client the address for this new port. The client will then get the new port number and would try to connect to the server on the new port.
2: The Echo thread - This starts a new listener on the port passed, and does the job of echoing to whoever is listening.
OR:
You start a UDP server rather than a TCP server, and all this will not matter then, but that is out of the purview of this specific question.

Sending RDF/XML using Sesame or Apache Jena with Sockets

I am trying to send RDF/XML from a Client to a Server using sockets in Java. When I send the information the Server program hangs and does not receive the info unless I close the Socket or OutputStream on the Client side. Even if I flush the OutputStream on the Client-side the Server does not receive the data unless I close the Socket/Stream. I would like to send the information without closing the socket. Here is some example code for the Client (using Sesame):
import java.io.*;
import java.net.*;
import org.openrdf.rio.*;
import org.openrdf.rio.helpers.*;
import org.openrdf.model.URI;
import org.openrdf.model.Model;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Statement;
import org.openrdf.model.impl.*;
import org.openrdf.model.vocabulary.*;
public class SimpleRDFClient {
private Socket socket = null;
public static void main(String[] args) {
new SimpleRDFClient(args[0],Integer.parseInt(args[1])).launch();
}
public SimpleRDFClient(String host, int port) {
try {
socket = new Socket(host,port);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void launch() {
try {
OutputStream out = socket.getOutputStream();
BufferedOutputStream dos = new BufferedOutputStream(out);
Model model = new LinkedHashModel();
ValueFactory factory = new ValueFactoryImpl();
URI clive = factory.createURI("http://www.site.org/cliveAnderson");
Statement st = factory.createStatement(clive, RDF.TYPE, FOAF.PERSON);
model.add(st);
Rio.write(model,dos,RDFFormat.RDFXML);
dos.flush();
//Some other stuff
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
And the Server Handler:
import java.io.*;
import java.net.*;
import org.openrdf.rio.*;
import org.openrdf.rio.helpers.*;
import org.openrdf.model.*;
import org.openrdf.model.impl.*;
public class SimpleRDFSHandler implements Handler {
public void handleConnection(Socket socket) {
Model model = null;
try {
InputStream in = socket.getInputStream();
model = Rio.parse(in,"www.blah.com",RDFFormat.RDFXML);
for (Statement st: model) {
System.out.println(st);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
The problem seems to come from the Rio.parse() method hanging (I think because it does not know when the input ends). I get a similar problem when I use the Jena api in a similar way, i.e. using Model.write(outputstream,format) and Model.read(inputstream,format) instead of Rio. I have looked at the source and the javadoc for ages but can't solve the problem. I think it must be something simple I have misunderstood. Any ideas?
I don't think this is in any way a Jena/Sesame specific issue but rather a Java issue around your use of sockets. Is there actually a practical reason you want to not close the socket?
I don't see why this would ever be advisable unless you want to continuously post data and process it as it is received on the server side? If this is the case both Jena and Sesame have APIs that specifically allow you to control what happens to data as it parsed in so that you aren't reliant on your read calls from completing before you process the data.
Also why use sockets, both Sesame and Jena have comprehensive HTTP integration which is much easier to use and deploy than rolling your own socket based server and clients.
The Ugly Hacky Solution
If you really must do this then there is a workaround but it is somewhat horrid and fragile and I would strongly recommend that you do not do this.
On the client side after you write the data write a sequence of bytes that indicate end of stream. On the server side wrap the socket stream with a custom InputStream implementation that recognizes this sequence and stops returning data when it is seen. This should allow the Jena/Sesame code which is expecting the stream to finish to function correctly.
The sequence of bytes need to be carefully chosen such that it won't naturally occur in the data.
To be honest this is a terrible idea, if your aim is to continuously post data this won't really solve your problem because then you'll just be leaking sockets server side unless you put the server side socket handling code in a while (true) loop which is likely another bad idea.

Exception in thread "main" java.net.BindException: Address already in use - Error in Netbeans only

On my machine, the following code compiles within Eclipse but throws an exception within Netbeans. The error message says "Exception in thread "main" java.net.BindException: Address already in use".
What is the proper configuration within Netbeans to make this code compile? It seems like the problem has to do with the fact that I have two main functions. If I start running either one of the apps, the second will fail to start, throwing the exception posted above.
Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
Server myServ = new Server();
myServ.run();
}
public void run() throws Exception {
ServerSocket mySS = new ServerSocket(9999);
Socket SS_accept = mySS.accept();
InputStreamReader mySR = new InputStreamReader(SS_accept.getInputStream());
BufferedReader myBR = new BufferedReader(mySR);
String temp = myBR.readLine();
System.out.println(temp);
}
}
Client.java
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
Client myCli = new Client();
myCli.run();
}
public void run() throws Exception {
Socket mySkt = new Socket("localhost", 9999);
PrintStream myPS = new PrintStream(mySkt.getOutputStream());
myPS.println("Hello server");
}
}
The problem is due to the fact that you left one instance of your server running and then started another one.
The way to achieve what I want is to right-click on the particular class (ex. Server.java) that I want to run and select "Run this file". This enables me to run only the Server app. Then, do the same process for the other file, Client.java.
However, Netbeans is somewhat confusing/deceiving in this particular circumstance. What Netbeans does is it runs the Server process, but labels that process as the name of the project (ex. MyTestNetworkingProject) and puts a run number on it, thus giving us MyTestNetworkingProject run #1 (it actually leaves out the #1 on the first process). Then, if I go to the Client.java file and select "Run this file", it generates a second process, MyTestNetworkingProject run #2. It then generates a second results window down at the bottom of the screen, as it generates these in new tabs as new processes get created.
Because of the nature of my specific code, what I wanted to see in my results window to confirm that my application was working was I wanted to observe the Server.java results window (which in this case is MyTestNetworkingProject run #1). Given my exact sequence of steps outlined above of running the different files, run #2 is the last run process and thus the tab on top, covering the run #1 tab. I can click on run #1 and see the results I was hoping to see in the console ("Hello server"), but I just have to know/remember that MyTestNetworkingProject run #1 represents the Server app and not the Client app.
Uncool, IMO.
If you write this in Windows OS,you can use "netstat -nao" to see which process use the 9999 port.If it is some unimportant process,you can kill this process.Otherwise you can change the port of the pragram.
I change the port address and it work for me in the Neat Beans IDE . This problem will come if we used the same port address for other one times . so to fix this error you have to change the port address and I am sure it will work
Server.java
public class SocServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(5001);
Socket client = server.accept();
DataOutputStream os = new DataOutputStream(client.getOutputStream());
os.writeBytes("Hello Sockets\n");
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java
public class SocClient {
public static void main(String[] args) {
try {
Socket socClient = new Socket("localhost", 5001);
InputStream is = socClient.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String receivedData = br.readLine();
System.out.println("Received Data: " + receivedData);
} catch (IOException e) {
e.printStackTrace();
}
}
}
refer above code and it works for me..
I did try the method catch and solved the problem.

Java NIO nonblocking: how to refuse incoming connections?

I'm trying to use server side code based on java NIO(non blocking) from 'The Rox Java NIO Tutorial'. There are lot of incoming socket connections and I would like to accept only 100. So if there are 100 active connections then new ones should be rejected/refused. But how to do that? There is only method ServerSocketChannel.accept() which returns SocketChannel object. Using that object I can call socketChannel.socket().close(), but connection is already open. Here is part of the code:
#Override
public void run() {
while (true) {
try {
// Wait for an event one of the registered channels
this.selector.select();
// Iterate over the set of keys for which events are available
Iterator selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
// Check what event is available and deal with it
if (key.isAcceptable()) {
this.accept(key);
} else if (key.isReadable()) {
this.read(key);
} else if (key.isWritable()) {
this.write(key);
}
}
} catch (Exception e) {
logger.warn("Reading data", e);
}
}
}
and accept() mehod:
private void accept(SelectionKey key) throws IOException {
// For an accept to be pending the channel must be a server socket channel.
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
// Accept the connection and make it non-blocking
if (noOfConnections < MAX_CONNECTIONS) {
SocketChannel socketChannel = serverSocketChannel.accept();
Socket socket = socketChannel.socket();
socket.setKeepAlive(true);
socketChannel.configureBlocking(false);
// Register the new SocketChannel with our Selector, indicating
// we'd like to be notified when there's data waiting to be read
socketChannel.register(this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);//listener for incoming data: READ from client, WRITE to client
noOfConnections++;
logger.info("Accepted: " + socket.getRemoteSocketAddress().toString());
} else {
// REJECT INCOMING CONNECTION, but how?
logger.warn("Server is full: " + noOfConnections + " / " + MAX_CONNECTIONS);
}
}
If connection is not accepted then accept() method is being called over and over.
Thanks for help!
There is no way to accomplish that, but I doubt that that's what you really want, or at least what you really should do.
If you want to stop accepting connections, change the interestOps in the server socket channel's selection key to zero, and change it back to OP_ACCEPT when you are ready to accept again. In the interim, isAcceptable() will never be true, so the problem you describe won't occur.
However that won't cause further connections to be refused: it will just leave them on the backlog queue where in my opinion and that of the designers of TCP they belong. There will be another failure behaviour if the backlog queue fills up: its effect in the client is system-dependent: connection refusals and/or timeouts.
I think any tuning of a backlog queue hardly ever would be a good solution. But probably, you can just stop listening.
Well, I managed this problem next way:
Pending-state connections on socket are in kind of "middle_state", that mean you cannot control/reject them.
Backlog socket parameter may be used/ignored/treated in different way by specific VM.
That mean you have to accept particular connection to receive associated object and operate it.
Use one thread to accept connection, pass accepted connection to second thread for processing.
Create some variable for number of active connections.
Now, while number of active connections is less than wished maximum, accept connection, rise the number by 1, and pass to second thread for processing.
Otherwise, accept connection and close that immediately.
Also, in connection process thread, than finished, decrease the number of active connections by 1 to point there is one more free channel available.
EDT: Just made the "stub" for server machanism for Java.Net NIO.
May be adapted for OP needs:
package servertest;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Servertest extends Thread {
final int MAXIMUM_CONNECTIONS = 3;
int connectionnumber = 0;
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args){
new Servertest().start();
}
#Override
public void run() {
try {
ServerSocket sc = new ServerSocket(33000, 50, InetAddress.getLoopbackAddress());
while (sc.isBound()) {
Socket connection = sc.accept();
if(connectionnumber<=MAXIMUM_CONNECTIONS){
new ClientConnection(connection).start();
connectionnumber++;
} else {
//Optionally write some error response to client
connection.close();
}
}
} catch (IOException ex) {
Logger.getLogger(Servertest.class.getName()).log(Level.SEVERE, null, ex);
}
}
private class ClientConnection extends Thread{
private Socket connection;
public ClientConnection(Socket connection) {
this.connection=connection;
}
#Override
public void run() {
try {
//make user interaction
connection.close();
} catch (IOException ex) {
Logger.getLogger(Servertest.class.getName()).log(Level.SEVERE, null, ex);
}
connectionnumber--;
}
}
}

Categories