I am trying to create a new thread inside a run method of currently running thread. But new thread is not getting started and it is blocking the execution of currently running thread.
Run method of currently running thread.
public void run() {
while(true){
try{
Message message = (Message)objIn.readObject();
System.out.println("Received msg:"+message);
if(message.type.equals("connection")){
if(message.content.equals("true")){
System.out.println("connection successful");
InetAddress senderIp = message.senderIp;
InetAddress receiverIp = message.receiverIp;
System.err.println(senderIp+"------"+receiverIp);
if(senderIp.getHostAddress().equals(receiverIp.getHostAddress())){
//first member of ring topology
System.err.println("first member");
}else{
System.err.println("not the first member");
ClientSideTempClient clientTemp = new ClientSideTempClient(receiverIp);
Thread obj1 = new Thread(clientTemp);
obj1.start();
System.out.println("after starting local client tread...");
}
}else{
System.out.println("something went wrong");
}
}
}catch(Exception e){
System.out.println("Exception:"+e);
}
}
}
Class for new thread:
ClientSideTempClient.java
public class ClientSideTempClient implements Runnable{
public Socket socket;
public ObjectInputStream objIn;
public ObjectOutputStream objOut;
public ClientSideTempClient(InetAddress serverIp){
try{
System.err.println("trying to connect"+serverIp.getHostAddress());
String ipAddress = serverIp.getHostAddress();
socket = new Socket(ipAddress, 9010);
objOut = new ObjectOutputStream(socket.getOutputStream());
objOut.flush();
objIn = new ObjectInputStream(socket.getInputStream());
}catch(Exception e){
System.err.println("Exception in ClientSideTempClient"+e);
}
}
public void sendMessageToLocalServer(Message msg){
try {
objOut.writeObject(msg);
objOut.flush();
System.out.println("Outgoing : "+msg.toString());
}catch(Exception e){
System.out.println("Exception in chatroom_client:"+e);
}
}
#Override
public void run() {
While(true){
System.out.println("Execution started here");
}
}
}
I searched number of related answers for this on google, but i am not getting solution of it. Can anyone guide me to solve this issue?
Your ClientSideTempClient class creates and connects the Socket in its constructor, which is delaying your loop. The Socket and the object streams should be created in its own run() method, i.e. on its own thread.
NB You must catch EOFException and break out of that loop if you get it. Most other IOExceptions are fatal too, except SocketTimeoutException.
Related
I followed a few tutorials and found out how to use threads for multithreading socket servers. I've created a Server class that has ClientServiceThread class for clients. When the thread receives a message from the client, how can I access that information using the Server class?
Here is my Server Thread:
public void run(){
game = new Game();
try{
serverSocket = new ServerSocket(port);
System.out.println("Server Started");
}
catch (IOException e){
System.out.println(e);
}
while(true) {
try {
Socket clientSocket = serverSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
threads.add(cliThread);
cliThread.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Here is my ClientServiceThread class:
public void run() {
boolean m_bRunThread = true;
System.out.println("Accepted Client Address - " + socket.getInetAddress().getHostAddress());
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
while(m_bRunThread) {
String clientCommand = in.readUTF();
System.out.println("Client Says :" + clientCommand);
if(!gameStarted) {
out.writeUTF("GAME_ALREADY_STARTED");
out.flush();
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
EDIT 1: Essentially, I'm listening to commands/messages on the client handler threads. I later want to process them into my Server so I can manipulate my Game object through it.
The approach I'd recommend is to pass the game object to the client threads (it has to be thread-safe!), and then let the client threads take the actions on the game object directly. This will simplify your server class, and give you a single place to handle incoming messages.
Alright, so I've coded what is going to be a simple communication program using a server, really as a test more than anything else, so I know it's missing a lot, but with the following Client class:
public class Client {
private ObjectInputStream in;
private ObjectOutputStream out;
private Socket socket;
private String server;
private int port;
public Client(String ip, int p){
port = p;
server = ip;
}
public boolean start(){
try{
socket = new Socket(server, port);
}catch(Exception e){
System.out.println("Exception");
e.printStackTrace();
return false;
}
try{
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("All declared");
}catch(Exception e){
System.out.println("Exception");
e.printStackTrace();
return false;}
new LThread().start();
return true;
}
private void sendMessage(Message msg){
try{
out.writeObject(msg);
}catch(Exception e){}
}
public static void main(String[] args){
int portNum = 1500;
String servers = "localhost";
Client client = new Client(servers, portNum);
System.out.println("Client started");
if(!client.start()){
System.out.println("Didn't work");
return;
}
System.out.println("Client started again");
Scanner scan = new Scanner(System.in);
while(true){
String i = scan.nextLine();
client.sendMessage(new Message(2, i));
}
}
class LThread extends Thread{
public void run(){
System.out.println("Lthread running");
while(true){
try{
String message = (String)in.readObject();
System.out.println(message);
}catch(Exception e){
e.printStackTrace();}
}
}
}
}
The program simply stops when it reaches the point at which it declares its ObjectInput and Output Streams. The program doesn't exit, it doesn't appear to enter the catch block, and I cannot, at all, figure out what on earth could possibly be causing it. The line "All declared." is never printed, but anything before it is printed. Could anyone please tell me why my program just ceases to function at this point without displaying any errors?
EDIT: I figure that there could be an error somewhere in my Server file, so here's the class:
public class Server {
private static int uid;
private ArrayList<ClientThread> clients;
private int port;
private boolean cont;
public Server(int p){
port = p;
clients = new ArrayList<ClientThread>();
}
public void start(){
System.out.println("Started");
cont = true;
try{
ServerSocket srvr = new ServerSocket(port);
System.out.println("Declared socket");
while(cont){
Socket sk = srvr.accept();
System.out.println("Socket accepted");
if(!cont)break;
ClientThread t = new ClientThread(sk);
clients.add(t);
t.start();
}
try{
srvr.close();
for(ClientThread t : clients){
t.in.close();
t.out.close();
t.socket.close();
}
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
}
private synchronized void broadcast(String msg){
for(int i=clients.size(); --i >= 0;){
ClientThread t= clients.get(i);
if(!t.writeMsg(msg)){
clients.remove(i);
}
}
}
public static void main(String[] args){
int portNum = 1500;
Server server = new Server(portNum);
server.start();
}
class ClientThread extends Thread{
Socket socket;
ObjectInputStream in;
ObjectOutputStream out;
String name;
int id;
Message m;
ClientThread(Socket s){
id = ++uid;
socket = s;
try{
System.out.println("Before");
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("After");
}catch(Exception e){
e.printStackTrace();}
}
public void run(){
boolean c = true;
while(c){
try{
m = (Message)in.readObject();
switch(m.getType()){
case 2:
broadcast(m.getMessage());
}
}catch (Exception e){
e.printStackTrace();}
}
}
public boolean writeMsg(String msg){
if(!socket.isConnected()){
return false;
}
try{
out.writeObject(msg);
}catch(Exception e){
e.printStackTrace();}
return true;
}
}
}
Alright, another edit. So I added those two printlns to the try statement in ClientThread's constructor, and, just like with client, it runs until I try to initialize the streams, and then it just stops. Again, no errors, no anything; it just completely stops in its tracks. I cannot figure out why on earth this happens, but if it means anything, I'm using the Eclipse IDE to run it.
I snagged on this the first time I used ObjectInputStream and ObjectOutputStream. At the root cause of your problem is within the constructor ObjectInputStream. The constructor will read from the underlying stream in an attempt to get header information such as the wire format version.
In order to prevent your client and server from infinity waiting for the other to send the information first, you should invert the order of the input and output streams, then flush the output stream explicitly. The following at the construction of the streams in the client and server will fix your problem:
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = new ObjectInputStream(socket.getInputStream());
I have the following code for sending data over a socket:
socketclient.java
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketClient
implements Runnable
{
private Socket socket;
private String ServerIP = "192.168.0.11";
private static final int ServerPort = 7000;
#Override
public void run()
{
try
{
socket = new Socket(ServerIP, ServerPort);
}
catch(Exception e)
{
System.out.print("Whoops! It didn't work on ip" + ServerIP + "!:");
System.out.print(e.getLocalizedMessage());
System.out.print("\n");
}
}
public void Send(String s)
{
try
{
Thread.sleep(10);
OutputStream out = socket.getOutputStream(); //Starts the output stream
PrintWriter output = new PrintWriter(out);
output.println(s); //sends the data over the socket
output.flush(); //flushes the outputwriter
output.close(); //closes the outputwriter
out.close(); //closes the outputstream
}
catch (UnknownHostException e) {
System.out.print(e.toString());
} catch (IOException e) {
System.out.print(e.toString());
}catch (Exception e) {
System.out.print(e.toString());
}
}
}
When i dont have the sleep in the send function the server output looks like this (i have it set to print the 'conn' and 'addr' of every connection), the server is coded in python
Connected with 192.168.0.11:52578
in client thread
Connected with 192.168.0.11:52579
in client thread
Connected with 192.168.0.11:52609
in client thread
and the server connection data recieveing/main connection thread is this:
def clientthread(conn):
#Sending message to connected client
#Receiving from client
data = conn.recv(4096)
print data
#came out of loop
conn.close()
My goal for the server is to open/close sockets on the client-side everytime i want to send data because i want each reciever to create its own connections using a socket class i created.
What is the reason for having to add a thread.sleep() before sending a string over a TCP socket in java?
Also, this is how i use my Socketclient class:
SMSClient = new SocketClient();
Thread thread = new Thread(SMSClient);
thread.start();
SMSClient.Send(smsData);
When you instantiate a new SocketClient object you are not running the new thread. You should call your Send(String s) method just after socket = new Socket(ServerIP, ServerPort); from inside the run method.
To know the current thread in your running code put some log like the following: Log.d("label", "thread id: "+android.os.Process.myTid()). Try for example to evaluate the current thread inside run method, and inside the Send(String s) method when you call this latter as you are doing and after having moved the call to the method inside the run.
I suggest to use IntentService for your purpose since, when needed, you can managed easily the socket connection and transmission in a separate thread.
When the thread.start() call returns the thread may not have executed yet. And then you are sending already your first request. You may wait with sleep after thread.start() that is better (while sleeping in the main thread the connection thread has a chance to run) - but still not best practice. Here is my working code ( I added a main function to the SocketClient ):
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketClient
implements Runnable
{
private Socket socket;
private String ServerIP = "127.0.0.1";
private static final int ServerPort = 7000;
#Override
public void run()
{
try
{
socket = new Socket(ServerIP, ServerPort);
}
catch(Exception e)
{
System.out.print("Whoops! It didn't work on ip" + ServerIP + "!:");
System.out.print(e.getLocalizedMessage());
System.out.print("\n");
}
}
public void Send(String s)
{
try
{
OutputStream out = socket.getOutputStream(); //Starts the output stream
PrintWriter output = new PrintWriter(out);
output.println(s); //sends the data over the socket
output.flush(); //flushes the outputwriter
output.close(); //closes the outputwriter
out.close(); //closes the outputstream
}
catch (UnknownHostException e) {
System.out.print(e.toString());
} catch (IOException e) {
System.out.print(e.toString());
}catch (Exception e) {
System.out.print(e.toString());
}
}
static public void main(String[] args)
{
SocketClient socketClient = new SocketClient();
Thread thread = new Thread(socketClient);
thread.start();
try
{
Thread.sleep(19);
}
catch(Exception e) {}
socketClient.Send("hallo");
}
}
So I don't know who to go about creating a multithreaded server. I have client and server working fine together but can't introduce multiple clients properly. Here is my Server code:
package dod;
import java.net.*;
import java.io.*;
import dod.game.GameLogic;
public class Server{
Server(GameLogic game, int port) throws IOException{
ServerSocket ss = null;
Socket sock = null;
try{
ss = new ServerSocket(4444);//port no.
while(true){
try{
sock = ss.accept();
ClientThread thread = new ClientThread(game, sock);
System.out.println("Adding new player...");
thread.run();
}catch(final Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}catch(Exception d){
System.out.println(d);
}finally{
if(ss!=null){
ss.close();
}
}
}
}
Here is my thread class:
package dod;
import java.io.*;
import java.net.Socket;
import dod.game.GameLogic;
import dod.game.PlayerListener;
public class ClientThread extends CommandLineUser implements PlayerListener, Runnable{
DataInputStream in;
PrintStream out;
// The game which the command line user will operate on.
// This is private to enforce the use of "processCommand".
ClientThread(GameLogic game, Socket sock) {
super(game);
try{
in = new DataInputStream(sock.getInputStream());
out = new PrintStream(sock.getOutputStream());
}catch(IOException ioe){
System.out.println(ioe);
}
game.addPlayer(this);
}
/**
* Constantly asks the user for new commands
*/
public void run() {
System.out.println("Added new human player.");
// Keep listening forever
while(true){
try{
// Try to grab a command from the command line
final String command = in.readLine();;
// Test for EOF (ctrl-D)
if(command == null){
System.exit(0);
}
processCommand(command);
}catch(final RuntimeException e){
System.err.println(e.toString());
System.exit(1);
} catch (final IOException e) {
System.err.println(e.toString());
System.exit(1);
}
}
}
/**
* Outputs a message to the player
*
* #param message
* the message to send to the player.
*/
public void outputMessage(String message) {
out.print(message);
}
}
Not asking for new code as such, just need pointers as to what I need to do have multiple client connection at the same time! Thanks to anyone who helps out!
To start, add new Thread(clientThread) in the server and call start() on it - as is everything's happening on the same thread.
public class Server{
Server(GameLogic game, int port) throws IOException{
ServerSocket ss = null;
Socket sock = null;
try{
ss = new ServerSocket(4444);//port no.
while(true){
try{
sock = ss.accept();
ClientThread thread = new ClientThread(game, sock);
System.out.println("Adding new player...");
thread.start(); //you have to use start instead of run method to create multi thread application.
}catch(final Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}catch(Exception d){
System.out.println(d);
}finally{
if(ss!=null){
ss.close();
}
}
}
}
You have to use start instead of run method to create multi thread application.
If you want to send messages about new connections you have to hold sock in a list and when a new connection accepted send message to all socket object in list. (server broadcasts to all connected sockets)
I hope it helps.
I've got a simple client and server that I've written to teach myself a bit of networking. The way it's set up is I've got a main server class which will deal with creating/destroying sockets, and the ConnectionThread class that represents each connection (each of which is given its own thread). The client is super simple.
The problem lies in creating the input/output streams in the ConnectionThread class. I'm not sure exactly what the problem is, but it crashes when the simple test client tries to connect, giving me this:
~~MMO Server Alpha .1~~
Constructed Server
Server Initialized, preparing to start...
Server preparing to check if it should be listening...
Server should be listening, continuing as planned.
ServerSocket passed to ConnectionThread: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=6969]
Constructing ConnectionThread.
Socket[addr=/10.0.1.10,port=55332,localport=6969]
ConnectionThread constructed.
Exception in thread "main" java.lang.NullPointerException
at ConnectionThread.init(ConnectionThread.java:65)
at Server.listen(Server.java:98)
at Server.start(Server.java:62)
at Server.main(Server.java:122)
ConnectionThread added to queue.
Establishing in and out streams:
null
Here are the classes (amended for brevity):
public class Server {
int PORT;
boolean shouldListen;
ArrayList<ConnectionThread> connections = new ArrayList<ConnectionThread>();
ServerSocket serverSocket;
public Server() {
try {
PORT = 6969;
shouldListen = true;
serverSocket = new ServerSocket(PORT);
}
catch (IOException e) {
System.out.println("Error in server constructor.");
System.exit(1);
}
}
public void start() {
System.out.println("Server preparing to check if it should be listening...");
listen();
System.out.println("Server finished listening.");
}
public void listen() {
while (shouldListen) {
ConnectionThread conn = null;
System.out.println("Server should be listening, continuing as planned.");
try {
conn = new ConnectionThread(serverSocket);
}
catch (Exception e) {
System.out.println("____Error constructing ConnectionThread. Could there be another instance of the server running?");
System.exit(1);
}
System.out.println("ConnectionThread constructed.");
connections.add(conn);
System.out.println("ConnectionThread added to queue.");
conn.init();
System.out.println("Finished ConnectionThread initialization, verifying...");
if (conn.isInitialized) {
System.out.println("ConnectionThread Initialized, preparing to start new thread.");
(new Thread(conn)).start();
}
}
}
public static void main(String[] args) {
System.out.println("~~MMO Server Alpha .1~~");
Server server = new Server();
System.out.println("Constructed Server");
server.init();
System.out.println("Server Initialized, preparing to start...");
server.start();
}
}
Here's the ConnectionThread class:
public class ConnectionThread implements Runnable {
boolean shouldBeListening = true;
boolean isThereAnUnsentOutgoingMessage = false;
String outgoingMessage = "OUTGOING UNINITIALIZED";
boolean IsThereAnUnsentIncomingMessage = false;
String incomingMessage = "INCOMING UNITIALIZED";
boolean isInitialized = false;
PrintWriter out;
BufferedReader in;
String currentInputMessage = "Test Input Message from the Server ConnectionThread";
String previousInputMessage = null;
Socket socket;
public ConnectionThread(ServerSocket s) {
System.out.println("ServerSocket passed to ConnectionThread: " + s);
/*
* The purpose of the constructor is to establish a socket
* as soon as possible. All transmissions/logic/anything else
* should happen in init() and/or run().
*/
System.out.println("Constructing ConnectionThread.");
try {
Socket socket = s.accept();
System.out.println(socket);
}
catch (IOException e) {
System.out.println("Error in ConnectionThread constructor");
System.exit(1);
}
}
public void init() {
/*
* Everything should be set up here before run is called.
* Once init is finished, run() should be set to begin work.
* This is to ensure each packet is efficiently processed.
*/
try {
System.out.println("Establishing in and out streams:");
System.out.println(socket);
out = new PrintWriter(socket.getOutputStream(), true);
System.out.println("ConnectionThread: Output Stream (PrintWriter) Established");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("ConnectionThread: InputStream (BufferedReader) Established");
}
catch (IOException e) {
System.out.println("Error in ConnectionThread method Init.");
System.exit(1);
}
isInitialized = true;
}
And optionally, here's the test client:
public class TestClient {
static PrintWriter out;
BufferedReader in;
public final int PORT = 6969;
Socket socket = null;
InetAddress host = null;
public TestClient() {
out = null;
in = null;
socket = null;
host = null;
}
public void connectToServer() {
System.out.println("Connecting to server...");
try {
host = InetAddress.getLocalHost();
socket = new Socket(host.getHostName(), PORT);
}
catch (Exception e) {
System.out.println("Error establishing host/socket");
System.exit(1);
}
try {
System.out.println("Establishing I/O Streams");
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e) {
System.out.println("Error establishing in/out streams");
System.exit(1);
}
}
public static void main(String[] args) {
System.out.println("~~TestClient Alpha .1~~");
TestClient c = new TestClient();
c.connectToServer();
System.out.println("Should be connected to server. Sending test message...");
while (true) {
System.out.println("here");
out.println("Hello there");
}
}
}
The 'socket' variable in the constructor of ConnectionThread shouldn't be local. It is shadowing the member variable.
It is customary to call accept() in the listen() loop, and pass the accepted socket to the ConnectionThread.
As EJP said, in your ConnectionThread constructor you think that you are assigning the value to the socket field, however you are actually assigning the value to the socket method variable, thus the socket field remains null, and in init() you see socket as null.
In addition to EJP answer: you did not provide ConnectionThread.run() method, but I assume you are going to use fields in, out and socket in your run() method. Since these fields are not marked as volatile or final, depending on your luck and number of core on your computer, you may also get NullPointerException at run() method.
This is because new variable value may be not propagated between caches and new thread will not see value of changed.
Explanation of this possible problem is here - The code example which can prove "volatile" declare should be used