I have the following code in which I spawn a thread listen which is supposed to constantly listen to any incoming TCP messages, after this thread is run I want the main thread to be used for sending messages but as soon as I initiate listen.run() it seems that main thread does not run any further. I want it to continue to run the while loop but it never reaches it.
package tcpclient;
import java.io.*;
import java.net.*;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
public class client {
//instance vars
static Socket cSocket =null;
static PrintWriter out = null;
static BufferedReader in = null;
//server info
static String serverName = null;
static int serverPort = 0;
static String userName=null;
//listening vars
static Thread listen;
static String incoming=null;
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
try {
System.out.println("\n\n\nTCP Chat Client\n\nEnter server name:");
Scanner scan = new Scanner(System.in);
//get server info from user
serverName = scan.nextLine();
System.out.println("\nEnter port number:");
serverPort = Integer.parseInt(scan.nextLine());
System.out.println("\nEnter your username:");
userName = scan.nextLine();
//make connection to server
cSocket = new Socket(serverName, serverPort);
out = new PrintWriter(cSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
//send username to server
out.println(userName);
//start listening
listen = new Thread(){
#Override
public void run(){
try {
incoming = in.readLine();
while (!(incoming.equals(null))) {
System.out.print(incoming);
incoming = in.readLine();
}
} catch (IOException ex) {
Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
listen.run();
String rcvrname="wefwef";
String message=null;
//start messaging
while(!(rcvrname.equals("exit"))){
System.out.println("Enter reciever name");
out.println(scan.nextLine());
System.out.println("Enter message");
out.println(scan.nextLine());
}
out.close();
in.close();
cSocket.close();
}
catch (UnknownHostException ex) {
System.err.println("\ncan't find that host\n");
}
catch (IOException ex) {
Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
}
finally{
in.close();
out.close();
cSocket.close();
}
}
}
You want:
listen.start();
not
listen.run();
Also the preferred way of doing this since Java 5 is to use an ExecutorService:
Runnable listen = new Runnable() {
public void run() { ... }
}
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.submit(listen);
and when you want to stop it:
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
or simply:
exec.shutdownNow();
Here is the problem:
listen.run();
You mustn't call run() itself! You should call start(), this spawns a thread, calling run() just call a function.
Related
I have a simple server and client code that I have been creating. Im new to networking and I have been stuck with this error for absolutely ages. I know that the message is there as I can output the message to console. I have very little idea why this is not working, ill link the code for both server and client and also the error below. Many thanks.
Server Code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package oserver;
import java.net.*;
import java.io.*;
import com.dosse.upnp.UPnP;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
/**
*
* #author sgmud
*/
public class SServer { // Server Class
public ServerSocket SSocket;
public Socket CSocket;
public PrintWriter out;
public BufferedReader in;
public int GetPort(){ // Gets port number for socket to be set listening to
Scanner scan = new Scanner(System.in);
System.out.println("please enter the port number");
int PortNum = scan.nextInt();
return PortNum;
}
public void start(int port) { // Starts the server with the collected port
try{
System.out.println("Server Started");
UPnP.openPortTCP(port);
SSocket = new ServerSocket(port);
CSocket = SSocket.accept();
System.out.println("Server Connected");
out = new PrintWriter(CSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(CSocket.getInputStream()));
Timer timer = new Timer();
int seconds;
seconds = 1;
timer.scheduleAtFixedRate(
new TimerTask()
{
public void run()
{
Listner();
}
},
0, // run first occurrence immediately
1000); // run every 1 seconds
SServer server = new SServer();
server.convosation();
/**
String input;
while ((input = in.readLine()) != null){
if(".".equals(input)){
out.println("goodbye");
break;
}
else{
out.println(input);
}
}
**/
}catch(IOException e){
System.out.println("ERROR");
}
}
public String Message(){
Scanner scan = new Scanner(System.in);
System.out.println("please enter a mesasge to be sent");
String message = scan.nextLine();
return message;
}
public void convosation(){ // method will keep letting you send a message untill you stop
SServer client = new SServer();
while (true){
Scanner scan = new Scanner(System.in);
System.out.println("Type QUIT to end the convosation or press any key to send a message");
String qit = scan.nextLine();
if("QUIT".equals(qit)){
client.STOP();
}
else{
client.sendMessage(client.Message()); // Runs the send message method with the output from the Message method
}
}
}
public void stop(){ // Will close all connections
try{
//in.close();
out.close();
CSocket.close();
SSocket.close();
}catch(IOException e){
System.out.println("ERROR");
}
}
public void sendMessage(String msg){
if(msg.equals("null")){
SServer client = new SServer();
client.sendMessage(client.Message());// outputs message
}
else{
out.println(msg);
}
//try{
// Response = in.readLine();
//}catch(IOException e){
// System.out.println("ERROR");
//}
//System.out.println(Response);
//return Response;
} // outputs message
public static void main(String[] args){
SServer server = new SServer(); // Creat new server class
server.start(server.GetPort()); // Starts the server with the port number
}
public void STOP(){
try{
in.close();
out.close();
CSocket.close();
}catch(IOException e){
System.out.println("ERROR");
}
}
public void Listner() {
String message = "";
try{
message = in.readLine();
}catch(IOException e){
}
if(message.equals("")==false){System.out.println(message);}
}
}
Client Code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package oclient;
import java.net.*;
import java.io.*;
import com.dosse.upnp.UPnP;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
/**
*
* #author sgmud
*/
public class CClient {
public Socket CSocket;
public PrintWriter output;
public BufferedReader in;
public int GetPort(){
Scanner scan = new Scanner(System.in);
System.out.println("please enter the port number");
int PortNum = scan.nextInt();
return PortNum;
}
public String GetAddress(){
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the IP address of the host");
String Address = scan.nextLine();
return Address;
}
public void StartConnection(String ip, int port){
try{
CSocket = new Socket(ip, port);
output = new PrintWriter(CSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(CSocket.getInputStream()));
Timer timer = new Timer();
int seconds;
seconds = 1;
timer.scheduleAtFixedRate(
new TimerTask()
{
public void run()
{
Listner();
}
},
0, // run first occurrence immediately
1000); // run every 1 seconds
CClient server = new CClient();
}catch(IOException e){
System.out.println("ERROR");
}
}
public void sendMessage(String msg){
if(msg.equals("null")){
CClient client = new CClient();
client.sendMessage(client.Message());// outputs message
}
else{
System.out.println(msg);
output.println(msg);
}
//try{
// Response = in.readLine();
//}catch(IOException e){
// System.out.println("ERROR");
//}
//System.out.println(Response);
//return Response;
} // outputs message
public String receveMessage(){
String Response = "null";
try{
Response = in.readLine();
}catch(IOException e){
System.out.println("Error");
return Response;
}
System.out.println(Response);
return Response;
}
public void convosation(){ // method will keep letting you send a message untill you stop
CClient client = new CClient();
while (true){
Scanner scan = new Scanner(System.in);
System.out.println("Type QUIT to end the convosation or press any key to send a message");
String qit = scan.nextLine();
if("QUIT".equals(qit)){
client.STOP();
}
else{
client.sendMessage(client.Message()); // Runs the send message method with the output from the Message method
}
}
}
public String Message(){
Scanner scan = new Scanner(System.in);
System.out.println("please enter a mesasge to be sent");
String message = scan.nextLine();
return message;
}
public void STOP(){
try{
in.close();
output.close();
CSocket.close();
}catch(IOException e){
System.out.println("ERROR");
}
}
public void Listner() {
String message = "";
try{
message = in.readLine();
}catch(IOException e){
}
if(message.equals("")==false){System.out.println(message);}
}
/**
*
* #param args
*/
public static void main(String[] args){
CClient client = new CClient(); // Making a new client class
client.StartConnection(client.GetAddress(), client.GetPort()); // runs the startConnection method but runs the Get address and Get port method first so the Start connection method has the IP and Port number
client.convosation();
// client.STOP(); // runs the stop method which will terminate the server
}
}
Error:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.io.PrintWriter.println(String)" because "this.output" is null
at oclient.CClient.sendMessage(CClient.java:79)
at oclient.CClient.convosation(CClient.java:122)
at oclient.CClient.main(CClient.java:169)
Sorry if I have been a bit vauge, I dont really see why this is not working. Also please ignoor my poor error handling, I plan on working on that later on. Any help is much appreaciated. :)
I got a minor issue. I want to use serversockets to send over a list of players to a client. But for some reason when I try to run the application it will stop at when it reaches socket = serverSocket.accept();. I tried serval things on google but doesn't work.
package Serverside;
import java.io.*;
import java.net.*;
import com.mygdx.game.Sprites.Hero;
import com.mygdx.game.Sprites.Player;
import java.util.ArrayList;
/**
*
* #author Tjidde Nieuwenhuizen
*/
public class ServerArenaOfLegends {
static ServerSocket serverSocket;
static Socket socket;
static ObjectOutputStream outStreamObj;
static ObjectInputStream inStreamObj;
static ArrayList<Player> playerList;
public static void main(String[] args) {
ServerArenaOfLegends sr = new ServerArenaOfLegends();
sr.run();
}
private void run() {
playerList = new ArrayList<Player>();
Player p1;
Hero hero = new Hero(2, null, 3);
p1 = new Player(null, null, hero);
playerList.add(p1);
try {
serverSocket = new ServerSocket(5555);
socket = serverSocket.accept();
outStreamObj = new ObjectOutputStream(socket.getOutputStream());
while (true) {
outStreamObj.writeObject(playerList);
}
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
}
If you run this example :
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5555);
Socket socket = serverSocket.accept();
System.out.println("DONE");
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
The program will appear to hang.
Then on the command line run "telnet 127.0.0.1 5555"
The program will then print "DONE" and then end.
So .accept() blocks until it gets data and this is the behavior you are seeing.
Every time a connection is made from the client to the server, the client sends a string message "11" to the server, and when the Server receives the string message "11" it operates count++. Then there has been two connections made, which should make count = 2 from count++ operating twice, but when the client connects, I checked it and the client sends the string message "11" correctly to the server, but the count stays as 1 and never enters the if(count == 2) block. Been testing and looking for hours but can't seem to locate the problem. Please help! Thank you
Client's snippet code:
Socket s = new Socket(hostname, port); // Plug in the socket to connect to the server
pw = new PrintWriter(s.getOutputStream()); //Instance of sending it out
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
public void run() { //Deal with reading from server and print them out
try {
pw.println("11"); //Sends the message when connection is made to the server
pw.flush();
} catch (Exception e) {
e.printStackTrace();
}
try{
while(true){
String line = br.readLine(); //Read in the message from server
if(line.equals("12")){ //When finally receives the string message "12" from server
button.setBackground(Color.white);
button.addActionListener(sl);
}
int update = Integer.parseInt(line);
if(update < 10){
current-= update;
}
}
} catch (IOException ioe){
System.out.println("ioe in ChatClient.run: " + ioe.getMessage());
}
}
Server thread's snippet code:
PrintWriter pw = new PrintWriter(s.getOutputStream());
public void run(){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
String line = br.readLine(); //blocking //Keep reading in messages
if(line.equals("11")){ //Tested it out and does receive "11" whenever a client connects and prints out "11"
count++; //But the problem is count stays as 1 every time it connects and never becomes 2
System.out.println(line);
System.out.println(count);
}
if(count == 2){ //Never able to reach inside this block of code
pw.println("12");
pw.flush();
count++;
}
}
} catch(IOException ioe){
System.out.println("ioe in ChatTHread: " + ioe.getMessage());
}
}
Edit - Server Code:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.Vector;
public class Server {
private int count = 0;
private Vector<FFThread> ctVector = new Vector<FFThread>(); //Parametrized
public Server(int port){
try{
ServerSocket ss = new ServerSocket(port); //Server socket to connect to the port
while(true){
Socket s = ss.accept(); // Listens for a connection to be made to this "s" socket and accepts it.
FFThread ct = new FFThread(s, this); //Get new socket access thread
ctVector.add(ct); //Appends the specified element "ct" to the end of this Vector.
ct.start();
}
} catch(IOException ioe){
System.out.println("ioe in ChatServer: " + ioe.getMessage());
}
}
public int counter(){
this.count = 0;
count++;
return count;
}
public void sendMessage(String message, FFThread ct){
for(FFThread c : ctVector ){
if(!c.equals(ct)){ //Two different clients
c.sendMessage(message);
}
}
}
public void removeThread(FFThread ct){
ctVector.remove(ct);
}
public static void main(String [] args){
Scanner scan = new Scanner(System.in);
System.out.print("What port? ");
int port = scan.nextInt();
new Server(port);
}
}
Edit - Server's thread class:
import java.awt.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
public class FFThread extends Thread {
private Socket s;
private Server cs;
private PrintWriter pw;
private int count = 0;
boolean ready = false;
public FFThread(Socket s, Server cs){
this.s = s;
this.cs = cs;
try{
this.pw = new PrintWriter(s.getOutputStream()); //Set up to send messages to clients
} catch(IOException ioe){
System.out.println("ioe in ChatThread constructor: " + ioe.getMessage());
}
}
Your Server class starts a new thread (instance of FFThread) for each incoming connection. Your run method of FFThread does count++, but it must be doing it on a local variable, since it's not accessing the count variable in the Server class. Therefore, each thread increments its own count from 0 to 1, and it never reaches two.
Your run method should increment (and test) the count variable of the Server instance in order for that count to reach 2. You'll have to increment it in a thread safe manner (i.e. with a synchronized method).
I believe adding the following to your Server class would work :
private volatile int count = 0;
...
public synchronized void incCount()
{
count++;
}
public int getCount()
{
return count;
}
Then, in your FFThread class, use this.cs.getCount() and this.cs.incCount() to read and increment the count.
I'm trying to figure out a way to get an instance of a server to negotiate between two clients by creating a chat thread between them.
I created this project, and it "almost" works... but it seems like there is a buffer of synch problem.
when writing a line in one side (i.e Client#1), it doesn't pass to the other side (i.e Client#2), but only after Client#2 trys to pass a line too.
I know there might be better ways to implement this, but I'd like to understand what's wrong with my code.
your help would be great!
the code:
server
import java.io.*;
import java.net.*;
public class Server
{
public static void main(String[] args)
{
int id = 1;
System.out.println();
System.out.println("Server");
try
{
ServerSocket serverSocket = new ServerSocket(4321);
while (true)
{
Socket client1Socket = serverSocket.accept();
Socket client2Socket = serverSocket.accept();
System.out.println("clients connected from ports: \n"
+ client1Socket.getPort() + ", " + client2Socket.getPort());
Thread client1Thread = new ServerThread(client1Socket, client2Socket, id);
client1Thread.start();
id++;
Thread client2Thread = new ServerThread(client2Socket, client1Socket, id);
client2Thread.start();
id++;
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
server thread
import java.io.*;
import java.net.*;
import java.util.*;
public class ServerThread extends Thread
{
Socket sourceSocket;
Socket destSocket;
int id;
public ServerThread(Socket src, Socket dst, int n)
{
sourceSocket = src;
destSocket = dst;
id = n;
}
public void run()
{
try
{
Scanner clientInput = new Scanner(sourceSocket.getInputStream());
PrintStream destOutput = new PrintStream(destSocket.getOutputStream());
destOutput.println("You are chatting with Client " + id);
boolean more = true;
while (more)
{
String input = clientInput.nextLine();
destOutput.println(input);
if (input.equals("Q"))
{
more = false;
}
}
sourceSocket.close();
destSocket.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
client
import java.io.*;
import java.net.*;
import java.util.*;
public class Client
{
public static void main(String[] args)
{
System.out.println();
System.out.println("Client");
try
{
Socket clientSocket = new Socket("localhost", 4321);
System.out.println("Connection Established");
Scanner input = new Scanner(clientSocket.getInputStream());
PrintStream output = new PrintStream(clientSocket.getOutputStream());
Scanner in = new Scanner(System.in);
System.out.println(input.nextLine());
boolean more = true;
while (more)
{
String text = in.nextLine();
output.println(text);
String nextInput = input.nextLine();
if (nextInput == null)
{
more = false;
}
else
{
System.out.println(nextInput);
}
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
In your client code, the line String text = in.nextLine(); will block your thread. That means if you never type in anything in your client, you can not receive anything. So the solution is to put your message receiving code in another thread. such as:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (!Thread.interrupted()) {
System.out.println(input.nextLine());
}
}
});
thread.start();
while (true)
{
String text = in.nextLine();
output.println(text);
// String nextInput = input.nextLine();
......................
}
I have a problem in running server-client program. When i run my server program , it keeps on running and never ends up. On other side, when i run my client program it throws an exception as shown below (my firewall is off).
The replies will be more than appreciated. Thanks
//Client Code
import java.io.*;
import java.net.*;
public class DailyAdviceClient
{
public void go()
{
try {
Socket s = new Socket("127.0.0.1", 4242);
InputStreamReader read = new InputStreamReader(s.getInputStream());
BufferedReader z = new BufferedReader(read);
String advice = z.readLine();
System.out.println("today you should" + advice);
z.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
DailyAdviceClient x = new DailyAdviceClient();
x.go();
}
}
//Server Code
import java.io.*;
import java.net.*;
public class DailyAdvisor
{
String[] advicelist = { "take your time", "be patient",
"don't be diplomatic", " life is really short", "try to fix things" };
public void go()
{
try
{
ServerSocket s = new ServerSocket(4242);
while (true)
{
Socket m = s.accept();
PrintWriter writer = new PrintWriter(m.getOutputStream());
String advice = getAdvice();
writer.println(advice);
writer.close();
writer.flush();
System.out.println(advice);
}
} catch (IOException ex)
{
ex.printStackTrace();
}
}
private String getAdvice()
{
int random = (int) (Math.random() * advicelist.length);
return advicelist[random];
}
public static void main(String[] args)
{
DailyAdvisor x = new DailyAdvisor();
x.go();
}
}
The Server never ends up because you used a while(true) loop. It is necessary for your server to keep listening to new client connections through the accept() method.
About the exception, your code runs fine both locally and using a remote machine. Thus a network configuration error could be the cause and you must check if both server/client could see each other using the ping command. If this is the case, then check if the server is listening to the client using netstat.