I have class that extends asynchronous task and another class which extends thread.
Client.java
public class Client extends AsyncTask<String, Void, Void>
{
Socket socket;
private SocketClient socketClient;
DataOutputStream out;
#Override
protected Void doInBackground(String... params)
{
// TODO Auto-generated method stub
Log.d("home","Client");
connect();
return null;
}
protected void connect()
{
// TODO Auto-generated method stub
Log.d("home","Connect");
if(socket!=null)
{
disconnect();
return;
}
try
{
String host = "111.111.1.111";
InetAddress in=InetAddress.getByName(host);
socket = new Socket(in,21);
socketClient=SocketClient.handle(this,socket);
Log.d("home","Connection established");
}
catch(Exception e)
{
e.printStackTrace();
Log.d("home","Not Connection established");
}
}
void disconnect()
{
// TODO Auto-generated method stub
try
{
socketClient.setDesonnected(true);
socket.close();
}
catch (Exception e)
{
System.err.println("Error closing client : "+e);
}
socket=null;
}
protected void sendmessage(byte[] commandchannel1)
{
// TODO Auto-generated method stub
byte[] commandchannel=commandchannel1;
try
{
if(out==null)
{
out=new DataOutputStream(socket.getOutputStream());
}
// out.writeInt(commandchannel.length);
out.write(commandchannel);
out.flush();
}
catch(Exception e)
{
e.printStackTrace();
disconnect();
}
}
public void setreceived(String got)
{
// TODO Auto-generated method stub
System.out.println(got);
}
}
SocketClient.java
public class SocketClient extends Thread
{
private boolean desonnected=false;
private static SocketClient socketClient=null;
private Socket socket=null;
private static Client parent;
private DataInputStream in;
customadapter customadapter;
public synchronized void setDesonnected(boolean cr)
{
desonnected=cr;
}
private SocketClient(Client parent, Socket s)
{
super("Client");
this.parent = parent;
socket=s;
setDesonnected(false);
start();
System.out.println(this.parent);
}
public static SocketClient handle(Client client, Socket socket)
{
// TODO Auto-generated method stub
if(socketClient==null)
socketClient=new SocketClient(parent, socket);
else {
if(socketClient.socket!=null) {
try {
socketClient.socket.close();
} catch (Exception e) {
}
}
socketClient.socket=null;
socketClient=new SocketClient(parent,socket);
}
return socketClient;
}
public void run() {
InputStream is = null;
try {
is = socket.getInputStream();
System.out.println(is);
in = new DataInputStream(is);
} catch(IOException e) {
try {
socket.close();
} catch(IOException e2) {
System.err.println("Socket not closed :"+e2);
}
System.out.println("Could not open socket : "+e.getMessage());
parent.disconnect();
return;
}
while(!desonnected) {
try {
String got = readInputStream(in); //in.readLine();
if(got==null) {
//parent.error("Connection closed by client");
parent.disconnect();
break;
}
**parent.setreceived(got);**
} catch(IOException e)
{
if(!desonnected)
{
System.out.println(e.getMessage());
parent.disconnect();
}
break;
}
}//end of while
try {
is.close();
in.close();
//socket.close();
} catch (Exception err) {}
socket=null;
}//end of run
private static String readInputStream(DataInputStream _in) throws IOException
{
StringBuilder sb=new StringBuilder();
String data = "";
int s = _in.read();
if(s==-1)
return null;
data += ""+String.format("%X", s)+ " ";
int len = _in.available();
System.out.println("Len got : "+len);
if(len > 0)
{
byte[] byteData = new byte[len];
_in.read(byteData);
for(byte b:byteData)
{
System.out.println(byteData);
sb.append(String.format("%02X",b));
sb.append(" ");
}
}
data += sb.toString();
System.out.println(data);
return data;
}
}
I am getting exception as Attempt to invoke virtual method on null pointer exception when setreceived(got) is called. How will i overcome this exception.
I am calling the asynchronous task from another Activity as
client=new Client();
client.execute();
I want to return the received value to an activity finally. How can i do this.
Please help.Thanks in Advance
You will have to change handle method. As for initializing SocketClient you have passed parameter parent, which is not initialized yet. So pass 'client' instead of it.
public static SocketClient handle(Client client, Socket socket)
{
// Verify that the socket is open
if(socketClient==null)
socketClient=new SocketClient(client, socket);
else {
if(socketClient.socket!=null) {
try {
socketClient.socket.close();
} catch (Exception e) {
}
}
socketClient.socket=null;
socketClient=new SocketClient(client,socket);
}
return socketClient;
}
Related
I have a socket communication between clients and a server. I design the server side in order to create a new thread every time a client connects to the server. The problem is that, sometimes, ObjectInputStream throws StreamCorruptedException when I try to read and object.
The involved classes implement serializable, and have correct serialVersionUIDs. Also, I used synchronized to avoid problems of synchronization. I tried to flush the objectOutputStream every time I write and object. The problem persist, so it is possible to send objects via a socket communication without use ObjectOutputStream? Send a byte array directly or something like this?
I let some code in case someone sees something I'm doing wrong.
server side
public class ClientHandler implements Runnable {
public static ArrayList<ClientHandler> clientsHandlers = new ArrayList<>();
private Socket socket;
private Server server;
private Usuario usuario;
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
public ClientHandler(Socket socket, Server server) {
try {
this.socket = socket;
this.server = server;
objectInputStream = new ObjectInputStream(socket.getInputStream());
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
clientsHandlers.add(this);
} catch (Exception e) {
// TODO: handle exception
disconnect();
}
}
#Override
public void run() {
// TODO Auto-generated method stub
while (!socket.isClosed() && socket.isConnected()) {
try {
synchronized (objectInputStream) {
Object object = objectInputStream.readObject(); // <---PROBLEM
if (object instanceof AccionOnline) {
switch (((AccionOnline) object).getTipoAccionOnline()) {
case DESCONECTAR:
disconnect();
if (server.numConnection == 0) {
server.closeServerSocket();
} else {
sendObject(object);
}
break;
case INICIARPARTIDA:
case DODECAEDRO:
case SIGUIENTE:
case DADO:
case ITEMDADO:
case RULETA:
case TEST:
case DRAWSTART:
case DRAW:
case DRAWUP:
sendObject(object);
break;
}
}
if (object instanceof Usuario) {
this.usuario = (Usuario) object;
for (ClientHandler clientHandler : clientsHandlers) {
if (!clientHandler.equals(this)) {
this.objectOutputStream.writeObject(clientHandler.usuario);
this.objectOutputStream.flush();
}
}
sendObject(object);
}
}
} catch (Exception e) { // TODO: handle exception closeAll(socket, bufferedReader,
disconnect();
}
}
}
public <T> void sendObject(T object) {
for (ClientHandler clientHandler : clientsHandlers) {
try {
clientHandler.objectOutputStream.writeObject(object);
clientHandler.objectOutputStream.flush();
} catch (Exception e) {
// TODO: handle exception
disconnect();
}
}
}
public void disconnect() {
System.out.println("cerrar conexion");
clientsHandlers.remove(this);
try {
if (objectInputStream != null) {
objectInputStream.close();
}
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (socket != null) {
socket.close();
}
server.numConnection--;
} catch (Exception e) {
// TODO: handle exception
}
}
}
client side
public class Client {
private Socket socket;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private ArrayList<GetObject> listeners = new ArrayList<>();
public Client(Socket socket, GetObject listener) {
listeners.add(listener);
try {
this.socket = socket;
this.objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
this.objectInputStream = new ObjectInputStream(socket.getInputStream());
} catch (Exception e) {
// TODO: handle exception
closeAll();
}
}
public void addListener(GetObject listener) {
listeners.add(listener);
}
public void removeListener(GetObject listener) {
listeners.remove(listener);
}
public <T> void sendObject(T object) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
objectOutputStream.writeObject(object);
} catch (Exception e) {
closeAll();
}
}
});
thread.start();
}
public void listenServer() {
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (socket.isConnected()) {
try {
Object o = objectInputStream.readObject();
for (GetObject listener : listeners) {
listener.getObject(o);
}
} catch (Exception e) {
// TODO: handle exception
closeAll();
}
}
}
}).start();
}
public void closeAll() {
try {
if (objectInputStream != null) {
objectInputStream.close();
}
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (socket != null) {
socket.close();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
i know there is alot of post that ask how to comunicate between client and server ,but in the majority those are generally people using the localhost, I have for project to use a vps and several client computer, unfortunately all the solutions given in the other post does not work, indeed the client does not seem to be able to connect to my vps
there is my client code
public IRCClient() throws IOException {
socket = new Socket(InetAddress.getByAddress(new byte[]{(byte) 185, (byte) 242, (byte) 180,97}), 2406);
messages = new LinkedBlockingQueue<Object>();
server = new ConnectionToServer(socket);
Thread messageHandling = new Thread() {
public void run() {
while (true) {
try {
Object message = messages.take();
parse(message);
System.out.println("Message Received: " + message);
} catch (InterruptedException e) {
}
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
private void parse(Object message) {
String msg = String.valueOf(message);
if (msg.contains("-")) {
if (msg.contains("key")) {
key = msg.split("-")[1];
} else if (msg.contains("name")) {
name = msg.split("-")[1];
} else if (msg.contains("world")) {
world = msg.split("-")[1];
} else if (msg.contains("server")) {
serverName = msg.split("-")[1];
} else if (msg.contains("x")) {
x = Integer.parseInt(msg.split("-")[1]);
} else if (msg.contains("y")) {
y = Integer.parseInt(msg.split("-")[1]);
} else if (msg.contains("z")) {
z = Integer.parseInt(msg.split("-")[1]);
} else if (msg.contains("isEntity")) {
entity = msg.split("-")[1].equalsIgnoreCase("true");
} else if (msg.contains("ticks")) {
lTicks = Integer.parseInt(msg.split("-")[1]);
} else if (msg.contains("end")) {
if (key.equalsIgnoreCase(MultiPingMod.getKey()) && !name.equalsIgnoreCase(Minecraft.getMinecraft().thePlayer.getName())) {
MultiPing m = new MultiPing(name, world, serverName, x, y, z, entity);
MultiPingMod.setTime(lTicks);
m.render = true;
if (MultiPingMod.render.getToRender().containsKey(name)) {
MultiPingMod.render.getToRender().get(name).render = false;
MultiPingMod.render.getToRender().remove(name);
}
MultiPingMod.render.addToRender(m);
}
}
}
}
public void send(Object obj) {
server.write(obj);
}
private class ConnectionToServer {
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
ConnectionToServer(Socket socket) throws IOException {
this.socket = socket;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
Thread read = new Thread() {
public void run() {
while (true) {
try {
Object obj = in.readObject();
messages.put(obj);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
};
read.setDaemon(true);
read.start();
}
private void write(Object obj) {
try {
out.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
i got this code from somewhere in this forum because after lot of attempt nothing was working
same for the server code here is :
public ServerListener() {
debug("Creating the server");
clientList = new ArrayList<ConnectionToClient>();
messages = new LinkedBlockingQueue<Object>();
debug("Client list is created");
try {
serverSocket = new ServerSocket(2406);
debug("opening the port 2406");
} catch (IOException e) {
e.printStackTrace();
debug(e.getMessage());
}
debug("creating the accept thread");
Thread accept = new Thread() {
public void run() {
debug("thread created");
while (true) {
try {
Socket s = serverSocket.accept();
if(s!=null) {
debug("new client joined");
clientList.add(new ConnectionToClient(s));
debug("new client was accepted ["+ s.getInetAddress() + "/" + s.getPort()+"]");
}
} catch (IOException e) {
e.printStackTrace();
debug(e.getMessage());
}
}
}
};
accept.setDaemon(true);
accept.start();
Thread messageHandling = new Thread() {
public void run() {
while (true) {
try {
Object message = messages.take();
debug("we parse the ping");
parse(message);
System.out.println("Message Received: " + message);
} catch (InterruptedException e) {
}
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
private void parse(Object message) {
String msg = String.valueOf(message);
if(msg.contains("-")) {
if(msg.contains("key")) {
debug("key detected");
key = msg.split("-")[1];
} else if(msg.contains("name")) {
debug("name detected");
name = msg.split("-")[1];
} else if(msg.contains("world")) {
debug("worldname detected");
world = msg.split("-")[1];
} else if(msg.contains("server")) {
debug("servername detected");
server = msg.split("-")[1];
} else if(msg.contains("x")) {
debug("x detected");
x = Integer.parseInt(msg.split("-")[1]);
} else if(msg.contains("y")) {
debug("y detected");
y = Integer.parseInt(msg.split("-")[1]);
} else if(msg.contains("z")) {
debug("z detected");
z = Integer.parseInt(msg.split("-")[1]);
} else if(msg.contains("isEntity")) {
debug("entity detected");
entity = msg.split("-")[1].equalsIgnoreCase("true");
} else if(msg.contains("ticks")) {
debug("ticks detected");
lTicks = Integer.parseInt(msg.split("-")[1]);
} else if(msg.contains("end")) {
debug("we got everything detected");
toSend = new IrcMPING(key, name, world, server, x, y, z, entity, lTicks);
for(String str : toSend.getArgs()) {
sendToAll(str);
}
toSend=null;
}
}
}
public void sendToOne(int index, Object message) throws IndexOutOfBoundsException {
clientList.get(index).write(message);
}
public void sendToAll(Object message) {
for (ConnectionToClient client : clientList) {
debug("sending the ping to " + client.socket.getInetAddress());
client.write(message);
}
}
public void debug(String str) {
System.out.println("SOROS DEBUG [MULTIPING] : " + str) ;
}
private class ConnectionToClient {
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
ConnectionToClient(Socket socket) throws IOException {
this.socket = socket;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
Thread read = new Thread() {
public void run() {
while (true) {
try {
Object obj = in.readObject();
messages.put(obj);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
};
read.setDaemon(true); // terminate when main ends
read.start();
}
public void write(Object obj) {
try {
out.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
i run the jar from the vps (who is based on debian) using the java jar command , but nothing to do i only get this on the terminal
https://cdn.discordapp.com/attachments/832578338567487497/833752196017029170/unknown.png //link to the image
How can i do to make this work ? there is any other way than socket to make two jar communicate from distant computer/server ? thank you for reading me and thank you if you try to help me
I wrote a SocketClient for connect to the socket, and add some callback in it.
public class SocketClientV2 {
public static void main(String[] args) {
SocketClientV2.Listener listener = new SocketClientV2.Listener() {
#Override
public void recv(byte[] result) {
// TODO Auto-generated method stub
System.out.println("====recv something");
}
#Override
public void connected() {
// TODO Auto-generated method stub
System.out.println("=====connected!");
}
#Override
public void disconnect() {
// TODO Auto-generated method stub
System.out.println("=====disconnect!");
}
};
SocketClientV2 client = new SocketClientV2("172.16.16.102", 4444,
10000, listener);
byte[] test = new byte[10];
test[0] = (byte) 0x1c;
test[1] = (byte) 0xff;
test[2] = (byte) 0x08;
client.send(test);
}
public interface Listener {
public void recv(byte[] result);
public void connected();
public void disconnect();
}
Socket client = null;
boolean isConnect = false;
OutputStream outputStream = null;
InputStream inputStream = null;
public SocketClientV2() {
}
Listener cb = null;
public SocketClientV2(String site, int port, int timeout, Listener cb) {
this.cb = cb;
try {
client = new Socket(site, port);
client.setSoTimeout(timeout);
System.out.println("Client is created! site:" + site + " port:"
+ port);
if (isConnected()) {
isConnect = true;
if (cb != null) {
cb.connected();
}
checkConnect();
listenRecv();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getClient() {
return this.client;
}
public void closeSocket() {
try {
isConnect = false;
inputStream.close();
outputStream.close();
client.close();
client = null;
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean isConnected() {
try {
client.sendUrgentData(0xff);
isConnect = true;
} catch (Exception e) {
System.out.println("return false....2");
isConnect = false;
e.printStackTrace();
return false;
}
return true;
}
private void checkConnect() {
new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("check connect....1");
try {
while (isConnected()) {
Thread.sleep(500);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("finally....3");
if (cb != null) {
cb.disconnect();
}
closeSocket();
}
}
}.start();
}
private void listenRecv() {
new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("listening Recv....");
try {
inputStream = client.getInputStream();
while (isConnect) {
byte[] result = readStream(inputStream);
if (cb != null) {
cb.recv(result);
}
Thread.sleep(500);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
public void send(final byte[] byteSend) {
new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
// System.out.println("sendMsg coming....");
if (isConnect) {
try {
outputStream = client.getOutputStream();
outputStream.write(byteSend);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
public byte[] readStream(InputStream inStream) throws Exception {
int count = 0;
while (count == 0) {
// System.out.println(0);
count = inStream.available();
// if(count!=0)
// System.out.println(count);
}
byte[] b = new byte[count];
inStream.read(b);
return b;
}
}
there is one thread checkConnect to check the connect status for the socket..
but it will disconnect after running few mins,
Client is created! site:172.16.16.102 port:4444
=====connected!
check connect....1
listening Recv....
====recv something
====recv something
====recv something
====recv something
====recv something
====recv something
====recv something
return false....2
java.io.IOException: Broken pipe
at java.net.PlainSocketImpl.socketSendUrgentData(Native Method)
at java.net.PlainSocketImpl.sendUrgentData(PlainSocketImpl.java:622)
at java.net.Socket.sendUrgentData(Socket.java:954)
at com.udpdemo.multicast.SocketClientV2.isConnected(SocketClientV2.java:100)
at com.udpdemo.multicast.SocketClientV2.access$0(SocketClientV2.java:98)
finally....3
=====disconnect!
at com.udpdemo.multicast.SocketClientV2$2.run(SocketClientV2.java:121)
java.io.IOException: Stream closed.
at java.net.PlainSocketImpl.available(PlainSocketImpl.java:483)
at java.net.SocketInputStream.available(SocketInputStream.java:217)
at com.udpdemo.multicast.SocketClientV2.readStream(SocketClientV2.java:205)
at com.udpdemo.multicast.SocketClientV2$3.run(SocketClientV2.java:154)
so what's problem with my sendUrgentData???
'Broken pipe' always means that you wrote to a connection which had already been closed by the peer. It's an application protocol error.
But unless the peer of this client isn't written in Java there is no point in using urgent data in the first place. Java can only receive urgent data 'in-line', i.e. after all the other pending data that had already been sent. And that only happens if the peer calls setOOBLine(true), otherwise
by default, this option is disabled and TCP urgent data received on a socket is silently discarded.
It's possible you're doing this to detect a broken connection. In this case, your dream came true, it worked, and all you have to do is adjust your catch and your code accordingly. But this is not in general a reliable technique.
Other notes:
isConnected() can never be false at the point you test it after creating the Socket, and it never magically becomes false afterwards. You need to revisit all the code that calls this method. Most of it doesn't make sense, or relies on false assumptions.
Your readStream() method spin-loops while available() returns zero. There is absolutely no point in this. You're just smoking the CPU. It's also completely at odds with your attempted use of a read timeout, which simply cannot possibly work while this loop is there. The following read() call will block until at least one byte of data arrives, or end of stream or an exception occurs. Your present code will never detect end of stream. You need to completely redesign this part of the code as well. It's poor practice to return a byte array for example.
That same piece of code completely ignores the count returned by read(). Never do that.
I'm creating this little client-server program to learn about sockets, and so far, I'm having a bit of trouble. For the purpose of this post, I consolidated the code into a single class. And the code will compile. (So it will show the same errors I get)
When the client connects to the server, the server socket properly creates a socket on the server-side. The Client then successfully sends a message to the server, but when the server tries to send a response to the client, there is an error saying the socket is closed.
Main.java
package main;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Hashtable;
public class Main {
boolean running = true;
public static void main(String[] args){
new Main().start();
}
public void start(){
new Thread(new ConnectionListener()).start(); //Starts Server
try {
connectToServer();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public class ConnectionListener implements Runnable{
public void run() {
ServerSocket ss = null;
try {
ss = new ServerSocket(31415);
}catch (BindException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
while(running){
try {
Socket sock = ss.accept();
ServerConnection c = new ServerConnection(sock);
c.start();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void connectToServer() throws UnknownHostException, IOException{
//Create Connection to Server
Socket socket = new Socket("localhost",31415);
ClientConnection cc = new ClientConnection(socket);
cc.start();
//Send First Message to Server
Hashtable<Integer, String> htt = new Hashtable<Integer, String>();
htt.put(0,"Hello, This is a Chat Test");
Message m = new Message(Message.Type.CHAT,htt);
cc.sendMessage(m);
}
public class ServerConnection{
Socket sock;
boolean connected = true;
public ServerConnection(Socket sock){
this.sock = sock;
}
public void start() {
new Thread(new RequestListener()).start();
}
private void handleMessage(Message m){
System.out.println("Server : Handle message " + m.type.toString());
}
public void disconnect(){
System.out.println("Disconnect user");
}
public void sendMessage(Message m){
try {
ObjectOutputStream os = new ObjectOutputStream(sock.getOutputStream());
os.writeObject(m);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class RequestListener implements Runnable{
public void run() {
ObjectInputStream is = null;
try {
is = new ObjectInputStream(sock.getInputStream());
while(connected){
try {
Message m = (Message)
is.readObject(); //EOFException
handleMessage(m);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch(SocketException e){
disconnect();
e.printStackTrace();
break;
}catch (IOException e) {
//e.printStackTrace(); //EOFException Here
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class ClientConnection {
private Socket socket;
private boolean connected = true;
public ClientConnection(Socket socket) {
this.socket = socket;
}
public void start(){
new Thread(new RequestListener()).start();
}
public void sendMessage(Message m){
try {
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.writeObject(m);
os.flush();
os.close();
} catch (IOException e) {
System.out.println("Error Sending Message");
e.printStackTrace();
}
}
public void close() throws IOException{
Message m = new Message(Message.Type.DISCONNECT,null);
sendMessage(m);
socket.close();
}
private void handleMessage(Message m){
System.out.println("Client : Handle message " + m.type.toString());
}
class RequestListener implements Runnable{
public void run() {
ObjectInputStream is = null;
try {
System.out.println(socket.isConnected()); //true
System.out.println(socket.isClosed()); //false
InputStream iss = socket.getInputStream();
is = new ObjectInputStream(iss); //socketClosedException
while(connected){
try {
Message m = (Message)is.readObject();
handleMessage(m);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch(SocketException e){
System.out.println("Server Disconnected");
break;
}catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
Message.java
package main;
import java.io.Serializable;
import java.util.Hashtable;
public class Message implements Serializable{
public enum Type{
LOGIN, PM, DISCONNECT, INCORRECT_LP,CORRECT_LP, UPDATE_USERLIST, CHAT, INCORRECT_VERSION
}
public Type type;
Hashtable ht;
public Message(Type type, Hashtable ht){
this.type = type;
this.ht = ht;
}
public Object get(Object o){
return ht.get(o);
}
}
There's nothing 'random' about it.
Closing the input or output stream of a Socket closes the other stream and the Socket.
In this case you are closing the ObjectOutputStream you have wrapped around the socket's output stream, which closes that output stream, which closes the socket's input stream and the socket.
I am trying to access the
public static List<ChatThread> Chat_list of my ChatThread Class
from the run() method of my Client Class but i keep getting an empty array(Infact it throws an exception at that point : Exception in thread "Thread-2" java.lang.NullPointerException)
and am very certain that that arrayList exists and is not empty(Because i did a test on the arrayList in my ChatThread Class). Just take a look at my code.
Please I need your help on what to do.
Thanks.
This is the class containing the arrayList :
public class ChatThread extends Thread {
private Socket sc;
private String cherry_name;
private String passwd;
public static List<ChatThread> Chat_list = new ArrayList<ChatThread>(); //THE STATIC ARRAY LIST
private BufferedReader br;
private BufferedWriter bw;
public ChatThread(Socket sc){
try {
this.sc=sc;
System.out.println(sc);
br = new BufferedReader(new InputStreamReader(sc.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(sc.getOutputStream()));
String help = br.readLine();
this.cherry_name=help.split("#")[0];
this.passwd=help.split("#")[1];
System.out.println(this.cherry_name);
System.out.println(this.passwd);
Chat_list.add(this); //This is where i add it to the arrayList
if(Chat_list.isEmpty()) //This is where i did the test
System.out.println("I am empty");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run(){
//Comparaison of information with that in the database
try{
bw.write("success");
bw.newLine();
bw.flush();
while(true){
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Socket getSc() {
return sc;
}
public String getCherry_name() {
return cherry_name;
}
}
As for the Client class :
public class Client extends Thread {
private Socket socket;
private BufferedReader br;
private BufferedWriter bw;
private ChatThread th;
private String cherry_name;
public Client(String cherry_name,String passwd){
try
{
socket = new Socket("127.0.0.1", 8888);
this.cherry_name=cherry_name;
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(cherry_name+"#"+passwd);
bw.newLine();
bw.flush();
}
catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Erreur lors de la lecture du socket");
e.printStackTrace();
}
}
#SuppressWarnings("deprecation")
public void run()
{
try {
String help = br.readLine();
if(help.equals("failed")){
this.notify();
this.destroy();
socket.close();
}
else{
if(ChatThread.Chat_list.isEmpty()) System.out.println("Empty array!!!"); //This is where it says the array is empty whereas it wasn't the case in the ChatThread Class
for(ChatThread ct : ChatThread.Chat_list){
if(cherry_name.equals(ct.getCherry_name())){
th=ct;
break;
}
}
while(true){
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Error whilst reading from the socket");
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("Interruption");
e.printStackTrace();
}
}
public Socket getSocket() {
return socket;
}
}
And my server class :
public class Server {
public static void main(String[] args) {
try {
ServerSocket server =new ServerSocket(8888);
Socket sc;
System.out.println("Server Started");
while(true){
sc=server.accept();
System.out.println("New Connection");
new ChatThread(sc).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
A main class to instantiate the Client class :
public class help {
public static void main(String[] argv) {
new Client("Jerry","Smith").start();
}
}
Every access to a mutable object shared between two threads must be accessed in a synchronized way. Not synchronizing will lead to visibility and coherence issues like you're seeing.
You should not expose an ArrayList like that (even without multiple threads, public static mutable objects are already a very bad practice). Instead, you should encapsulate it in your own object, and make sure every access is synchronized properly.
It's hard to give a more concrete advice without seeing any line of your code.