Run Thread In background - java

I have looked around and found different ways of doing this, all of which seem to generate an error. Here is what I am trying to run. It's connecting to a server which is already running.
Any ideas on how to get this to work or change it so it does work?
String serverAddress = MainActivity.serverAddress;
int port = MainActivity.newport;
Socket socket = new Socket(serverAddress, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
String getName=MainActivity.name;
// Process all messages from server, according to the protocol.
while (true) {
String line = in.readLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName);
}
else if (line.startsWith("NAMEACCEPTED")) {
//textField.setEditable(true);
}
else if (line.startsWith("MESSAGE")) {
mt.append(line.substring(8) + "\n");
}
}

What is it that aint working? Is it the code itself or do you need help on running this while(true) loop as a thread?
The while(true) loop will hog the main java thread so you wont be able to do any other operations outside of the while-loop. So first I would recommend to make the operations inside of the while-loop to a thread by either implement runnable or create an anonymous class and start the thread.
There are lots of examples on this: Java - creating a new thread
Hope this helps! Message me back if i interpreted your question wrong.

Related

Java Socket Server - Client; Stuck on Server side

This is the first time I am not able to find the problem/bug in my code so now I am asking stackoverflow xD
I am currently learning how to write a simple Server - Client network to understand how Sockets and Server Sockets in Java work. Therefore, I wrote a "program" consisting of a Server, Client and Handler class. The Handler class is responsible for receiving the Client's messages and sending a response. Sending from Server to Client works perfectly fine, the Client receives the message. However, when the Client sends a message to the Server, it does not receive anything. The BufferedReader I am using is stuck on the readLine() request.
//This is the broken down version of what is happening in my Handler class
ServerSocket server = new ServerSocket(port); //These two lines of code actually happen in the Server class
Socket client = server.accept(); //but to simplify it I put them here
//Setting up the IO
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
//The Handler is waiting for the Reader to be ready and then prints the input
//Additionally, it sends a confirmation to the client
while(true) {
String input;
if(in.ready()){
if ((input = in.readLine()) != null) {
System.out.println(input);
out.println("Message Received");
if(input=="close") break;
}
}
}
//Expected output: "Message Received"
//Actual ouput: none, it gets stuck at in.ready() or in.readLine()
When I send a message from the Client it should just print the message and send a confirmation to the client but instead it either never gets past the if(in.ready()){...} part or gets stuck at if((input=in.readLine())!=null){...} if I remove the first if-statement. I used IntelliJ to debug it and the InputStream doesn't contain any message or the carriage return which is expected by readLine(). I find that to be really weird as the sending and receiving part of both the Server as well as the Client class is (mostly) the same.
The only thing I could think of that would maybe be the cause of this problem is that the Client somehow has problems sending the message.
//This is the broken down version of what is happening in my Client class
Socket client = new Socket();
client.connect(new InetSocketAddress("localhost",port));
//Setting up the IO
Scanner scanner = new Scanner(System.in); //I am using a Scanner for the message inputs
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
String input;
System.out.println("Enter the first Message: ");
while ((input = scanner.nextLine()) != null) {
String inServer;
System.out.println(input); //The input is correct
out.println(input); //I am suspecting it has something to do with this line or the PrintWriter
//This part works perfectly fine here while it does not in the Handler class
if (in.ready()) {
if ((inServer = in.readLine()) != null) {
System.out.println(inServer);
}
}
System.out.println("Enter next Message: ");
}
Expected output: inServer
Actual output: inServer
As you can see, the general setup of this part is the same as in the Handler class, yet something seems to go wrong when sending to the Server. I don't know if it is the Server (I don't think so because the same code for receiving messages works just fine in the Client class) or the Client, where in that case it would have to be a problem with the PrintWriter or something like that.
I have already looked at other/ similar questions here on stackoverflow but didn't find anything that would solve my problem.
The full code for the classes if someone wants to replicate everything in detail: (Pastebin links)
Server class
Client class
Handler class
Well, it seems the question has been answered...
It seems like it had something to do with the IntelliJ project the code was in. I had to move it into a new project and now it works.
The issue is resolved now and if someone wants to use this code as a base for a Server-Client system, I'll leave the pastebin-links working.
My suggestion is that you use read() method of the classes that implement Reader (BufferedReader is one of them). The syntax would be like this :
String data = "";
int i;
while ((i = in.read()) != -1){
data += (char)i;
}
This way is a lot more reliable and does not have the carriage return problem.

Java - Clients won't receive data from server despite server receiving data from clients

I've got a fairly simple multi-thread chat program, where a server receives data from multiple clients and is then supposed to relay the messages back to all clients.
While the server does receive all its data properly, I can't seem to make the clients receive the returned values.
I've read through plenty of code and suggestions from both StackOverflow and other forums, but I can't seem to find the issue.
The ServerThread has the PrintWriter "out", declared and grabbed as such:
private PrintWriter out;
public PrintWriter getWriter(){
return out;
}
public void run() {
try{
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
This method in the ServerThread is supposed to pass the data along:
if(input != null){
//Loggs message to file:
loggMessage(input);
//Loggs message to Server GUI
setOutput(input);
//Prints message to Output
System.out.println(input);
//Sends message to other clients:
for(ServerThread c : UserList){
System.out.println("Client discovered");
PrintWriter clientwriter = c.getWriter();
clientwriter.write(input);
System.out.print(input + " <-- was written to client");
}
}
The console (and file) get all messages as expected, but the clients don't. This is, as far as I can tell, either caused by something being off with that line in this batch of code, or something being wrong clientside
Clientside:
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
The "in" is declared like that, a few rows before the following chunk of code:
if(in.ready()){
String serverin = in.readLine();
System.out.println(serverin);
setOutput(serverin);
}
This system.out.print doesn't print anything. This makes me believe that something is wrong already at the if, but I'm not sure what that would be.
So, the clients won't receive the messages, and I'm not sure why.
When the program is run, the server indicates that all clients have been found and messages appropriately, yet they won't receive anything.
Any ideas?
I think that this call to in.ready() is wrong.
if(in.ready()){
String serverin = in.readLine();
System.out.println(serverin);
setOutput(serverin);
}
There is no need to call ready() because in.readline() will wait(block) until there is input.
An other issue is that readline() will wait(block) until the server send a newline, and only return the string once it gets a newline so are you sure that input contains a newline?
So, after quite a lot of testing and comparing code, I've finally found the issue.
The "clientwriter.write(input)" should have been "clientwriter.println(input)". After changing that the whole system worked as intended.

How do you set a timeout on BufferedReader and PrintWriter in Java 1.4?

How does one set a timeout on a BufferedReader and a PrintWriter created using a socket connection? Here is the code I have for the server right now, which works until either the server or the client crashes:
while(isReceiving){
str = null;
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
while ((str = br.readLine()) != null){
System.out.println("Processing command " + str);
pw.println(client.message(str));
}
}
Outside the scope of this code I have imposed a socket timeout of 1000ms, which works as intended when waiting for the initial connection. But the program blocks at (str = br.readLine()). If the client hangs or crashes, it never stops blocking unless I terminate the process (which even then doesn't always work).
The client code in question is very similar to this, and is blocking in a similar fashion.
You need to set a read timeout on the socket, with Socket.setSoTimeout(). This will cause any read method to throw a SocketTimeoutException if the read timeout specified expires. NB Read timeouts are set not on the stream but on the underlying Socket, via Socket.setSoTimeout().
There is no such thing as a write timeout in TCP.
You could use SimpleTimeLimiter from Google's Guava library.
Sample code (in Java 8):
BufferedReader br = ...;
TimeLimiter timeLimiter = new SimpleTimeLimiter();
try {
String line = timeLimiter.callWithTimeout(br::readLine, 10, TimeUnit.SECONDS);
} catch (TimeoutException | UncheckedTimeoutException e) {
// timed out
} catch (Exception e) {
// something bad happened while reading the line
}
An answer in this question describes an interesting method using a Timer to close the connection. I'm not 100% sure if this works in the middle of a read, but it's worth a shot.
Copied from that answer:
TimerTask ft = new TimerTask(){
public void run(){
if (!isFinished){
socket.close();
}
}
};
(new Timer()).schedule(ft, timeout);
isFinished should be a boolean variable that should be set to true when you're done reading from the stream.
Since calling socket.close() did not seem to interrupt the block at br.readLine(), I did a little workaround. When disconnecting the client from the server, I merely send through a string "bye", and told the server to close the socket connection when it receives this command.
while ((str = br.readLine()) != null){
// If we receive a command of "bye" the RemoteControl is instructing
// the RemoteReceiver to close the connection.
if (str.equalsIgnoreCase("bye")){
socket.close();
break;
}
System.out.println("Processing command " + str);
pw.println(client.message(str));
}

Problem with a blocking network task

I'm new in Java so please forgive any obscene errors that I may make :)
I'm developing a program in Java that among other things it should also handle clients that will connect to a server. The server has 3 threads running, and I have created them in the following way :
DaemonForUI du;
DaemonForPort da;
DaemonForCheck dc;
da = new DaemonForPort(3);
dc = new DaemonForCheck(5);
du = new DaemonForUI(7);
Thread t_port = new Thread(da);
Thread t_check = new Thread(dc);
Thread t_ui = new Thread(du);
t_port.setName("v1.9--PORTd");
t_check.setName("v1.9-CHECKd");
t_ui.setName("v1.9----UId");
t_port.start();
t_check.start();
t_ui.start();
Each thread handles a different aspect of the complete program. The thread t_ui is responsible to accept asynchronous incoming connections from clients, process the sent data and send other data back to the client. When I remove all the commands from the previous piece of code that has to with the t_ui thread, everything runs ok which in my case means that the other threads are printing their debug messages.
If I set the t_ui thread to run too, then the whole program blocks at the "accept" of the t_ui thread.
After reading at online manuals I saw that the accepted connections should be non-blocking, therefore use something like that :
public ServerSocketChannel ssc = null;
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(port));
ssc.configureBlocking(false);
SocketChannel sc = ssc.accept();
if (sc == null) {
;
}
else {
System.out.println("The server and client are connected!");
System.out.println("Incoming connection from: " + sc.socket().getRemoteSocketAddress());
in = new DataInputStream(new BufferedInputStream(sc.socket().getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(sc.socket().getOutputStream()));
//other magic things take place after that point...
The thread for t_ui is created as follows :
class DaemonForUI implements Runnable{
private int cnt;
private int rr;
public ListenerForUI serverListener;
public DaemonForUI(int rr){
cnt = 0;
this.rr = rr;
serverListener = new ListenerForUI();
}
public static String getCurrentTime() {
final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
return (sdf.format(cal.getTime()));
}
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + "\t (" + cnt + ")\t (every " + rr + " sec) # " + getCurrentTime());
try{
Thread.sleep(rr * 1000);
cnt++;
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
Obviously, I'm doing something wrong at the creation of the socket or at the use of the thread. Do you know what is causing the problem?
Every help would be greatly appreciated.
Don't use non-blocking I/O until you know you need it. Just start a new thread for every accepted socket, as well as for the accepting threads.
Problem solved :)
I looked at your suggestions and had a closer look at the code. It was a design error since I had a function that created a while(true) loop inside the constructor of DaemonForUI (and more specifically inside ListenerForUI()). It was causing the whole program to cycle through the while statement, therefore stalling every other action.
Silly mistake I must admit... :(
Thanks for all the help everyone that answered my question.
I will consider the mentioned idea of creating a new thread for every incoming connection. The duty that has to be performed for every incoming connection is not so heavy, so I thought that one single thread could do the job.

How to close a thread in Java?

I'm very new to Java, and I'm trying to modify an example of a socket server to power a flash-based game. To allow flash to connect to the server, I need to serve up a policy file.
I've never coded a server application before, so I'm not too familiar with the things which need to happen.
Anyway, I have made it so that it outputs the file, but for some reason it does so 10 times.
I need to close the thread before it continues to do it again. Below is the code I have, with a comment where I need to close the thread.
import java.io.*;
import java.net.*;
import java.util.Random;
public class Main {
private static int port=4041, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;
try{
ServerSocket listener = new ServerSocket(port);
Socket server;
while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;
server = listener.accept();
doComms conn_c= new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private String line,input;
doComms(Socket server) {
this.server=server;
}
public void run () {
char EOF = (char)0x00;
input="";
try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintStream out = new PrintStream(server.getOutputStream());
while((line = in.readLine()) != null && !line.equals(".")) {
input=input + line;
if(line.trim().equals("h")){
out.println("h"+EOF);
}
else if(line.trim().equals("i")){
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(4);
out.println("b"+randomInt+EOF);
}
else if(line.trim().equals("c")){ System.out.println("Player collision.");}
else if (line.trim().equals("<policy-file-request/>")) {
out.println("<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy>\n<site-control permitted-cross-domain-policies=\"all\"/>\n<allow-access-from domain=\"*\"/>\n</cross-domain-policy>"+EOF);
System.out.println("Responded to policy request");
// I need to close the thread / disconnect the client here.
}
else System.out.println("Unknown command: "+line.trim());
}
server.close();
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
Also, a small extra thing, in NetBeans, it underlines "import java.io.*;" and says incorrect package, but it still works fine.
Edit:
I've worked out that the reason it sends it 10 times is that it is receiving 10 lines in a single send operation. I have tried adding a "return;" under where it sends the policy XML, but it still doesn't seem to d/c the client. I should also note than I am intending for this to be a multiplayer server, so I need to keep the socket open and just close one thread.
At first glance, your run() method looks like it should terminate normally. I suspect your loop:
while((i++ < maxConnections) || (maxConnections == 0)){
Since maxConnections is initialized to 0 and is never incremented, the loop seems to run infinitely and create many threads - probably as many as the socket can accept listeners. And then it breaks out from the loop with an IOException. Is this what's actually happening?
Update: apparently not... out of ideas for now.
Your code makes sense. What is your input? If you have 10 lines saying "<policy-file-request/>" , then indeed it will print the file 10 times. What about all the other if clauses you have there? In each one you print something + EOF, but surely you just want to print one response per request. Also your 'input' variable is unused.
The thread will die after you return from doComms.run(). Please capitalize the start of class names in Java: it should be DoComms, just to make the code easier to follow for other Java programmers.
To close the connection, your call to server.close() should do it. To make sure the output is sent fully first, you should call close() or flush() on your PrintStream before you call Socket.close().
What input are you sending? It looks like if you only send <policy-file-request/> once from the client, you'll only get the file once.
Not sure about NetBeans, but is it complaining that you don't have a package specified at the top of your .java file? Try adding the following package declaration, with the path relative to the top of the NetBeans project:
package my.path.to.this.directory;
I'd suggest running both the server and the client in a debugger and stepping through the execution to see what happens at each point in time. This will help you confirm the expected values at every point. Eclipse and other Java IDEs have pretty good (and easy-to-use) debuggers.
As far as your code:
I would do line.trim() once for each
loop iteration, instead of
trim()'ing repeatedly and
unnecessarily creating extra
objects.
Make sure the client and server both flush() the Socket's OutputStream after each request/response. If the socket's OutputStream has not been flushed, the InputStream on the other end of the connection may block waiting for input, while the OutputStream blocks waiting to fill its buffer.
What does the code in the client
look like? Are you sure it's
sending a null or "." to close the
connection? Do you need to trim() before checking for a "."
As others have mentioned, your code does not follow typical Java coding conventions. I'd suggest getting up to speed by reading the published code conventions for Java.

Categories

Resources