I am trying to develop some kind of chat application (learning purposes) but when I send my objects from the client to the server only the first one seems to get received. No error is shown or nothing so I don't really know whats wrong.
Server code:
import chattychat.domain.Message;
import chattychat.domain.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* #author
*/
public class Server {
private final int PORT;
private ServerSocket server;
public Server(){
this.PORT = 6565;
}
public Server(int port){
this.PORT = port;
}
public void listenSocket(){
try{
this.server = new ServerSocket(this.PORT);
} catch (IOException e) {
System.out.println("Could not listen on port 4444");
System.exit(-1);
}
while(true){
ClientWorker w;
try{
//server.accept returns a client connection
w = new ClientWorker(server.accept());
Thread t = new Thread(w);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
}
}
}
class ClientWorker implements Runnable {
private Socket client;
private ObjectInputStream in;
//Constructor
ClientWorker(Socket client) {
this.client = client;
}
public void run(){
try{
this.in = new ObjectInputStream(this.client.getInputStream());
Object obj = this.in.readObject();
System.out.println("called");
if(obj instanceof Message){
Message msg = (Message)obj;
System.out.println(msg);
}else if(obj instanceof User){
User user = (User)obj;
System.out.println(user);
}
System.out.println();
}catch (IOException e) {
System.out.println("Read failed");
//System.exit(-1);
} catch (ClassNotFoundException ex) {
System.out.println("Object not found");
//System.exit(-1);
}
}
}
#Override
protected void finalize(){
try{
this.server.close();
} catch (IOException e) {
System.out.println("Could not close socket");
System.exit(-1);
}
}
public static void main(String[] args){
Server s = new Server();
//s.communicate();
s.listenSocket();
}
}
Client code:
import chattychat.domain.Message;
import chattychat.domain.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
/**
*
* #author laurensputseys
*/
public class Client {
private final int PORT = 6565;
private String SERVER = "localhost";
private Socket socket;
private ObjectInputStream in;
private ObjectOutputStream out;
private boolean isConnected;
public Client(){
this.isConnected = false;
}
public Client(String server){
this.SERVER = server;
}
public String getServer(){
return this.SERVER;
}
public int getPort(){
return this.PORT;
}
public void communicate(Message msg){
while(!isConnected){
try{
this.socket = new Socket(this.getServer(), this.getPort());
isConnected = true;
this.out = new ObjectOutputStream(this.socket.getOutputStream());
this.out.writeObject(msg);
this.out.flush();
this.out.close();
}catch(SocketException se){
se.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
public void register(User usr){
while(!isConnected){
try{
this.socket = new Socket(this.getServer(), this.getPort());
isConnected = true;
this.out = new ObjectOutputStream(this.socket.getOutputStream());
this.out.writeObject(usr);
this.out.flush();
this.out.close();
}catch(SocketException se){
se.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
public boolean isConnected(){
return isConnected;
}
public static void main(String[] args){
Client c = new Client();
User u1 = new User("firstname 1", "lastname1", "testuser");
User u2 = new User("firstname 2", "lastname2", "Testuser");
Message m1 = new Message(u1, u2, "Hello from P1 to P2");
Message m2 = new Message(u2, u1, "Hello from P2 to P1");
System.out.println("Send 1");
c.communicate(m1);
System.out.println("Send 2");
c.communicate(m2);
System.out.println("Send 3");
c.register(u1);
}
}
message class:
import java.io.Serializable;
import java.util.Objects;
/**
*
* #author
*/
public class Message implements Serializable{
private static final long serialVersionUID = 7526472295622776147L;
private User from;
private User to;
private String message;
public Message(User from, User to, String message){
this.setFrom(from);
this.setTo(to);
this.setMessage(message);
}
private void setFrom(User from){
this.from = from;
}
private void setTo(User to){
this.to = to;
}
private void setMessage(String message){
this.message = message;
}
public String getMessage(){
return this.message;
}
#Override
public boolean equals(Object o){
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
Message tmpMsg = (Message)o;
return this.to.equals(tmpMsg.to) && this.from.equals(tmpMsg.from) && this.getMessage().equals(tmpMsg.getMessage());
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + Objects.hashCode(this.from);
hash = 59 * hash + Objects.hashCode(this.to);
hash = 59 * hash + Objects.hashCode(this.message);
return hash;
}
#Override
public String toString(){
return "From: " + this.from + " to: " + this.to + " message: " +this.getMessage();
}
}
User class:
import java.io.Serializable;
import java.util.Objects;
/**
*
* #author
*/
public class User implements Serializable{
private static final long serialVersionUID = 7526456787322776147L;
private String firstname;
private String lastname;
private String password;
public User(String firstname, String lastname, String password){
setFirstname(firstname);
setLastname(lastname);
setPassword(password);
}
private void setFirstname(String firstname){
this.firstname = firstname; //TODO
}
private void setLastname(String lastname){
this.lastname = lastname; //TODO
}
private void setPassword(String password){
this.password = password; //TODO
}
#Override
public boolean equals(Object o){
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
User tmpUser = (User)o;
return this.firstname.equals(tmpUser.firstname) && this.lastname.equals(tmpUser.lastname);
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.firstname.length();
hash = 59 * hash + this.lastname.length();
hash = 59 * hash + this.password.length();
return hash;
}
#Override
public String toString(){
return this.firstname + " " + this.lastname;
}
}
Thanks in advance!
Without reading your code very thoroughly. Your clients communicate methods sets connected to true on the first call. So the while loop will not be entered on the second call to communicate. You should separate connecting to server and sending messages. Also, your client worker thread in server seems to return after one object read. The run method should return when connection is broken, not when one message is read.
Related
I am using WebSocketClient class to get the data from websocket in my android app but when anything change in Internet connection ( Disconnect from Internet ) it gives the following error in WebSocketClient.java file
USER_COMMENT=null
ANDROID_VERSION=10
APP_VERSION_NAME=0.0.1
BRAND=google
PHONE_MODEL=Android SDK built for x86_64
CUSTOM_DATA=
STACK_TRACE=java.lang.AssertionError
at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:190)
at java.lang.Thread.run(Thread.java:919)
But the WebSocketClient.java is read only file it is coming from java-websocket-1.3.0.jar file
WebSocketClient.java
package org.java_websocket.client;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.CountDownLatch;
import org.java_websocket.SocketChannelIOHelper;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketAdapter;
import org.java_websocket.WebSocketFactory;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.WrappedByteChannel;
import org.java_websocket.WebSocket.READYSTATE;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.exceptions.InvalidHandshakeException;
import org.java_websocket.handshake.HandshakeImpl1Client;
import org.java_websocket.handshake.Handshakedata;
import org.java_websocket.handshake.ServerHandshake;
public abstract class WebSocketClient extends WebSocketAdapter implements Runnable {
protected URI uri;
private WebSocketImpl conn;
private SocketChannel channel;
private ByteChannel wrappedchannel;
private Thread writethread;
private Thread readthread;
private Draft draft;
private Map<String, String> headers;
private CountDownLatch connectLatch;
private CountDownLatch closeLatch;
private int timeout;
private WebSocketClient.WebSocketClientFactory wsfactory;
private InetSocketAddress proxyAddress;
public WebSocketClient(URI serverURI) {
this(serverURI, new Draft_10());
}
public WebSocketClient(URI serverUri, Draft draft) {
this(serverUri, draft, (Map)null, 0);
}
public WebSocketClient(URI serverUri, Draft draft, Map<String, String> headers, int connecttimeout) {
this.uri = null;
this.conn = null;
this.channel = null;
this.wrappedchannel = null;
this.connectLatch = new CountDownLatch(1);
this.closeLatch = new CountDownLatch(1);
this.timeout = 0;
this.wsfactory = new DefaultWebSocketClientFactory(this);
this.proxyAddress = null;
if (serverUri == null) {
throw new IllegalArgumentException();
} else if (draft == null) {
throw new IllegalArgumentException("null as draft is permitted for `WebSocketServer` only!");
} else {
this.uri = serverUri;
this.draft = draft;
this.headers = headers;
this.timeout = connecttimeout;
try {
this.channel = SelectorProvider.provider().openSocketChannel();
this.channel.configureBlocking(true);
} catch (IOException var6) {
this.channel = null;
this.onWebsocketError((WebSocket)null, var6);
}
if (this.channel == null) {
this.conn = (WebSocketImpl)this.wsfactory.createWebSocket(this, draft, (Socket)null);
this.conn.close(-1, "Failed to create or configure SocketChannel.");
} else {
this.conn = (WebSocketImpl)this.wsfactory.createWebSocket(this, draft, this.channel.socket());
}
}
}
public URI getURI() {
return this.uri;
}
public Draft getDraft() {
return this.draft;
}
public void connect() {
if (this.writethread != null) {
throw new IllegalStateException("WebSocketClient objects are not reuseable");
} else {
this.writethread = new Thread(this);
this.writethread.start();
}
}
public boolean connectBlocking() throws InterruptedException {
this.connect();
this.connectLatch.await();
return this.conn.isOpen();
}
public void close() {
if (this.writethread != null) {
this.conn.close(1000);
}
}
public void closeBlocking() throws InterruptedException {
this.close();
this.closeLatch.await();
}
public void send(String text) throws NotYetConnectedException {
this.conn.send(text);
}
public void send(byte[] data) throws NotYetConnectedException {
this.conn.send(data);
}
public void run() {
if (this.writethread == null) {
this.writethread = Thread.currentThread();
}
this.interruptableRun();
assert !this.channel.isOpen();
}
private final void interruptableRun() {
if (this.channel != null) {
try {
String host;
int port;
if (this.proxyAddress != null) {
host = this.proxyAddress.getHostName();
port = this.proxyAddress.getPort();
} else {
host = this.uri.getHost();
port = this.getPort();
}
this.channel.connect(new InetSocketAddress(host, port));
this.conn.channel = this.wrappedchannel = this.createProxyChannel(this.wsfactory.wrapChannel(this.channel, (SelectionKey)null, host, port));
this.timeout = 0;
this.sendHandshake();
this.readthread = new Thread(new WebSocketClient.WebsocketWriteThread());
this.readthread.start();
} catch (ClosedByInterruptException var3) {
this.onWebsocketError((WebSocket)null, var3);
return;
} catch (Exception var4) {
this.onWebsocketError(this.conn, var4);
this.conn.closeConnection(-1, var4.getMessage());
return;
}
ByteBuffer buff = ByteBuffer.allocate(WebSocketImpl.RCVBUF);
try {
while(this.channel.isOpen()) {
if (SocketChannelIOHelper.read(buff, this.conn, this.wrappedchannel)) {
this.conn.decode(buff);
} else {
this.conn.eot();
}
if (this.wrappedchannel instanceof WrappedByteChannel) {
WrappedByteChannel w = (WrappedByteChannel)this.wrappedchannel;
if (w.isNeedRead()) {
while(SocketChannelIOHelper.readMore(buff, this.conn, w)) {
this.conn.decode(buff);
}
this.conn.decode(buff);
}
}
}
} catch (CancelledKeyException var5) {
this.conn.eot();
} catch (IOException var6) {
this.conn.eot();
} catch (RuntimeException var7) {
this.onError(var7);
this.conn.closeConnection(1006, var7.getMessage());
}
}
}
private int getPort() {
int port = this.uri.getPort();
if (port == -1) {
String scheme = this.uri.getScheme();
if (scheme.equals("wss")) {
return 443;
} else if (scheme.equals("ws")) {
return 80;
} else {
throw new RuntimeException("unkonow scheme" + scheme);
}
} else {
return port;
}
}
private void sendHandshake() throws InvalidHandshakeException {
String part1 = this.uri.getPath();
String part2 = this.uri.getQuery();
String path;
if (part1 != null && part1.length() != 0) {
path = part1;
} else {
path = "/";
}
if (part2 != null) {
path = path + "?" + part2;
}
int port = this.getPort();
String host = this.uri.getHost() + (port != 80 ? ":" + port : "");
HandshakeImpl1Client handshake = new HandshakeImpl1Client();
handshake.setResourceDescriptor(path);
handshake.put("Host", host);
if (this.headers != null) {
Iterator i$ = this.headers.entrySet().iterator();
while(i$.hasNext()) {
Entry<String, String> kv = (Entry)i$.next();
handshake.put((String)kv.getKey(), (String)kv.getValue());
}
}
this.conn.startHandshake(handshake);
}
public READYSTATE getReadyState() {
return this.conn.getReadyState();
}
public final void onWebsocketMessage(WebSocket conn, String message) {
this.onMessage(message);
}
public final void onWebsocketMessage(WebSocket conn, ByteBuffer blob) {
this.onMessage(blob);
}
public final void onWebsocketOpen(WebSocket conn, Handshakedata handshake) {
this.connectLatch.countDown();
this.onOpen((ServerHandshake)handshake);
}
public final void onWebsocketClose(WebSocket conn, int code, String reason, boolean remote) {
this.connectLatch.countDown();
this.closeLatch.countDown();
if (this.readthread != null) {
this.readthread.interrupt();
}
this.onClose(code, reason, remote);
}
public final void onWebsocketError(WebSocket conn, Exception ex) {
this.onError(ex);
}
public final void onWriteDemand(WebSocket conn) {
}
public void onWebsocketCloseInitiated(WebSocket conn, int code, String reason) {
this.onCloseInitiated(code, reason);
}
public void onWebsocketClosing(WebSocket conn, int code, String reason, boolean remote) {
this.onClosing(code, reason, remote);
}
public void onCloseInitiated(int code, String reason) {
}
public void onClosing(int code, String reason, boolean remote) {
}
public WebSocket getConnection() {
return this.conn;
}
public final void setWebSocketFactory(WebSocketClient.WebSocketClientFactory wsf) {
this.wsfactory = wsf;
}
public final WebSocketFactory getWebSocketFactory() {
return this.wsfactory;
}
public InetSocketAddress getLocalSocketAddress(WebSocket conn) {
return this.channel != null ? (InetSocketAddress)this.channel.socket().getLocalSocketAddress() : null;
}
public InetSocketAddress getRemoteSocketAddress(WebSocket conn) {
return this.channel != null ? (InetSocketAddress)this.channel.socket().getLocalSocketAddress() : null;
}
public abstract void onOpen(ServerHandshake var1);
public abstract void onMessage(String var1);
public abstract void onClose(int var1, String var2, boolean var3);
public abstract void onError(Exception var1);
public void onMessage(ByteBuffer bytes) {
}
public ByteChannel createProxyChannel(ByteChannel towrap) {
return (ByteChannel)(this.proxyAddress != null ? new WebSocketClient.DefaultClientProxyChannel(towrap) : towrap);
}
public void setProxy(InetSocketAddress proxyaddress) {
this.proxyAddress = proxyaddress;
}
private class WebsocketWriteThread implements Runnable {
private WebsocketWriteThread() {
}
public void run() {
Thread.currentThread().setName("WebsocketWriteThread");
try {
while(!Thread.interrupted()) {
SocketChannelIOHelper.writeBlocking(WebSocketClient.this.conn, WebSocketClient.this.wrappedchannel);
}
} catch (IOException var2) {
WebSocketClient.this.conn.eot();
} catch (InterruptedException var3) {
}
}
}
public interface WebSocketClientFactory extends WebSocketFactory {
ByteChannel wrapChannel(SocketChannel var1, SelectionKey var2, String var3, int var4) throws IOException;
}
public class DefaultClientProxyChannel extends AbstractClientProxyChannel {
public DefaultClientProxyChannel(ByteChannel towrap) {
super(towrap);
}
public String buildHandShake() {
StringBuilder b = new StringBuilder();
String host = WebSocketClient.this.uri.getHost();
b.append("CONNECT ");
b.append(host);
b.append(":");
b.append(WebSocketClient.this.getPort());
b.append(" HTTP/1.1\n");
b.append("Host: ");
b.append(host);
b.append("\n");
return b.toString();
}
}
}
The third-party library has a description. You can write a class to inherit the WebSocketClient class and rewrite the code after network disconnection and reconnection. The code example of the third-party library is provided for reference.
I try to make a chat. When a client send a message to the server, it is working, the server receives the message. So I would like to send this message all the clients. I tried many things but they are not working... Just the client which sends the message, it receives this message
Can You help me please ?
Thanks in advance
PS : Sorry for my bad English
This is the result in the console :
http://i.stack.imgur.com/VS2wf.png
MainClient
public class MainClient {
/**
* #param args the command line arguments
* #throws java.io.IOException
* #throws java.lang.ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
boolean stop = false;
Socket socket;
Scanner nickScan;
String nick;
socket = new Socket(InetAddress.getLocalHost(), 2009);
System.out.println("Hi, what is your name ?");
nickScan = new Scanner(System.in);
nick = nickScan.nextLine();
User u = new User(nick, false, false, true);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(u);
EmissionThread e = new EmissionThread(u, socket);
e.start();
while(!stop){
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Message m = (Message)ois.readObject();
System.out.println(m.getNick() + " : " + m.getMsg());
}
//socket.close();//On ferme les connexions
}
}
MainServer
public class MainServer extends Thread {
public static void main(String[] args) throws InterruptedException, IOException {
// TODO code application logic here
ConnectionThread c = new ConnectionThread();
c.start();
}
}
ConnectionThread
public class ConnectionThread extends Thread {
private static final boolean stop = false;
Socket socketduserveur;
ServerSocket socketserver;
Session s = new Session("#upec");
public ConnectionThread() throws IOException {
this.socketserver = new ServerSocket(2009);
}
public ServerSocket getSocketserver() {
return socketserver;
}
#Override
public void run() {
while (!stop) {
try {
socketduserveur = socketserver.accept(); //On accepte les connexions
ObjectInputStream ois = new ObjectInputStream(socketduserveur.getInputStream());
User u = (User)ois.readObject();
System.out.println(u.getNick() + " c'est connecté");
s.addUserList(u);
if (s.listAlone()) {
System.out.println("Vous etes admin");
u.setAdmin(true);
}
ReceptionThread r = new ReceptionThread(socketduserveur);
r.start();
} catch (ClassNotFoundException ex) {
Logger.getLogger(MainServer.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ConnectionThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
ReceptionThread
public class ReceptionThread extends Thread {
private static final boolean stop = false;
Socket socketduserveur;
ServerSocket socketserver;
public ReceptionThread(Socket socketduserveur) {
this.socketduserveur = socketduserveur;
}
#Override
public void run() {
while (!stop) {
try {
ObjectInputStream ois = new ObjectInputStream(socketduserveur.getInputStream());
Message m = (Message)ois.readObject();
System.out.println(m.getNick() + " : " + m.getMsg());
ObjectOutputStream oos = new ObjectOutputStream(socketduserveur.getOutputStream());
oos.writeObject(m);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(ReceptionThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
EmissionThread
public class EmissionThread extends Thread {
private User u;
private Socket socketduserveur;
private static final boolean stop = false;
public EmissionThread(User u, Socket socketduserveur) {
this.u = u;
this.socketduserveur = socketduserveur;
}
#Override
public void run() {
while (!stop) {
try {
Scanner msgScan;
String msg;
msgScan = new Scanner(System.in);
msg = msgScan.nextLine();
Message m = new Message(u.getNick(), msg);
ObjectOutputStream oos = new ObjectOutputStream(socketduserveur.getOutputStream());
oos.writeObject(m);
} catch (IOException ex) {
Logger.getLogger(EmissionThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Message
public class Message implements Serializable {
private String nick;
private String msg;
public Message(String nick, String msg) {
this.nick = nick;
this.msg = msg;
}
}
Session
public class Session implements Serializable {
private String name;
private ArrayList<String> listSession = new ArrayList();
private ArrayList<User> listUser = new ArrayList();
public Session(String name) {
this.name = name;
}
public void addSession(String name){
listSession.add(name);
}
public void deleteSession(String name){
for(String s : listSession){
if(name.equals(s)){
listSession.remove(s);
}
}
}
public boolean existSession(String name){
for(String s : listSession){
if(name.equals(s)){
return true;
}
}
return false;
}
public void addUserList(User u){
listUser.add(u);
}
public boolean listAlone(){
int compteur = 0;
for(User u : listUser){
compteur++;
}
return compteur == 1;
}
}
User
public class User implements Serializable {
private String nick;
private final Session session;
private boolean admin, moderator, voice;
public User(String nick, boolean admin, boolean moderator, boolean voice) {
this.nick = nick;
this.admin = admin;
this.moderator = moderator;
this.voice = voice;
this.session = new Session("#upec");
}
}
You can use websockets on tomcat for this. If you download tomcat there is a chat app already built as an example
Based on this tutorial and another tutorial that unfortunately I can't get my hands on right now, I've created my Client-Server application but instead of sending string messages, the client asks for data(using Object Input/Output Streams) from the server using a custom class "Message".
First I created, the basic concept of it, using simple Java and tested both the server and the client on my computer, and displayed the data my client received in the console output. Everything worked out great, so I started to make the transition to Android(for the client). Trying to use the AsycTask, as show in the linked tutorial, I've managed so far to establish the connection between the client and the server. But I'm having a problem getting my server to read my "Message" object. Here are my classes:
Server:
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class T_Server extends Thread {
private static int port = 4444;
private ServerSocket srvSock = null;
private Socket clntSock = null;
private boolean running = false;
private ObjectInputStream in;
private ObjectOutputStream out;
private OnMessageReceived msgListener;
private Message msgIn;
private Object objSend;
public static void main(String[] args) {
OnMessageReceived _msgListener=new OnMessageReceived();
T_Server server=new T_Server(_msgListener);
server.start();
}
public T_Server(OnMessageReceived _msgListener) {
this.msgListener = _msgListener;
}
public void send(Object _msg) {
if (out != null) {
try {
out.writeObject(_msg);
out.flush();
} catch (IOException ex) {
Logger.getLogger(T_Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
#Override
public void run() {
running = true;
try {
srvSock = new ServerSocket(port);
System.out.println("Server startet. IP : " + InetAddress.getLocalHost() + ", Port : " + srvSock.getLocalPort());
System.out.println("\nWaiting for a client ...");
clntSock = srvSock.accept();
System.out.println("\nClient accepted: " + clntSock);
try {
out = new ObjectOutputStream(clntSock.getOutputStream());
in = new ObjectInputStream(clntSock.getInputStream());
while (running) {
msgIn = (Message) in.readObject();
System.out.println(msgIn.toString());
objSend = msgListener.messageReceived(msgIn);
send(objSend);
}
} catch (Exception e) {
System.out.println("S: Error");
e.printStackTrace();
} finally {
clntSock.close();
}
} catch (Exception e) {
System.out.println("S: Error");
e.printStackTrace();
}
}
}
I use the same Message class both on the Server and on the Client
Message Class:
import java.io.Serializable;
public class Message implements Serializable{
private static final long serialVersionUID = 1L;
public String sender, content, type;
public Message(String sender, String type, String content){
this.sender = sender; this.type=type; this.content = content;
}
#Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"'}";
}
}
I have also created a class to handle the Messages, on the server side, called OnMessageReceived.
P.S. In this class there are fields and some options that have to do with my backend database.
OnMessageReceived:
import java.sql.SQLException;
import java.util.regex.Pattern;
public class OnMessageReceived {
public Object messageReceived(Message message) throws SQLException {
Message _msg = message;
Database db = new Database();
Object objReturn;
String strResult;
boolean addResult;
final Pattern pattern = Pattern.compile("\\[.*?&");
final String[] result;
if (_msg.type.equals("getUsers")) {
objReturn = db.getUsers();
return objReturn;
} else if (_msg.type.equals("getFriends")) {
objReturn = db.getFriends(_msg.sender);
return objReturn;
} else if (_msg.type.equals("addFriend")) {
String _UserName, _UserNameFriend;
_UserName = _msg.sender;
_UserNameFriend = _msg.content;
addResult = db.addFriend(_UserName, _UserNameFriend);
if (addResult) {
strResult = "Add was successfull";
return strResult;
} else if (!addResult) {
strResult = "Add failed";
return strResult;
}
System.out.println(addResult);
} else if (_msg.type.equals("addUser")) {
String _UserName, _Password, _Phone;
result = pattern.split(_msg.content);
_UserName = _msg.sender;
_Password = result[0];
_Phone = result[1];
addResult = db.addUser(_UserName, _Password, _Phone);
if (addResult) {
strResult = "Add was successfull";
return strResult;
} else if (!addResult) {
strResult = "Add failed";
return strResult;
}
System.out.println(addResult);
} else if (_msg.type.equals("Login")) {
boolean isUser;
String _UserName;
_UserName = _msg.sender;
isUser = db.isUser(_UserName);
if (isUser) {
strResult = "Login Successfull";
return strResult;
} else if (!isUser) {
strResult = "Login failed";
return strResult;
}
}
return null;
}
}
For the client side(on the Android) it's very simillar to the one in the linked tutorial.
The difference is that I only have 2 buttons, one to connect to the server and one to send my message, which is an instance of my Message class.
Client:
import java.io.*;
import java.net.*;
import android.util.Log;
public class T_Client {
private static final String TAG = "MyActivity";
private static String serverIP = "192.168.1.11";
private static int port = 4444;
private InetAddress serverAddr = null;
private Socket sock = null;
private boolean running = false;
private ObjectInputStream in;
private ObjectOutputStream out;
private OnMessageReceived msgListener;
Object objIn, objReceived;
public T_Client(OnMessageReceived _msgListener){
this.msgListener=_msgListener;
}
public void send(Message _msg) {
if (out != null) {
try {
out.writeObject(_msg);
out.flush();
Log.i(TAG,"Outgoing : " + _msg.toString());
} catch (IOException ex) {
Log.e(TAG,ex.toString());
}
}
}
public void stopClient(){
running = false;
}
public void run(){
running = true;
try {
//here you must put your computer's IP address.
serverAddr = InetAddress.getByName(serverIP);
Log.i("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
sock = new Socket(serverAddr, port);
try {
//send the message to the server
out =new ObjectOutputStream(sock.getOutputStream());
//receive the message which the server sends back
in =new ObjectInputStream(sock.getInputStream());
Log.i("TCP Client", "C: Connected.");
//in this while the client listens for the messages sent by the server
while (running) {
objIn = in.readObject();
if (objIn != null && msgListener != null) {
//call the method messageReceived from MyActivity class
msgListener.messageReceived(objIn);
}
objIn = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + objIn + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
sock.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
public interface OnMessageReceived {
public void messageReceived(Object objReceived);
}
}
Main Activity:
import java.io.IOException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
private static final String TAG = "MyActivity";
private T_Client client;
private Message msgSend;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void connect(View v) throws IOException {
new connectTask().execute("");
}
public void btnSend(View v) throws IOException {
msgSend=new Message("Setlios", "getUsers", "");
if(client!=null){
client.send(msgSend);
}
}
public class connectTask extends AsyncTask<Object,Object,T_Client> {
#Override
protected T_Client doInBackground(Object... objIn) {
//we create a TCPClient object and
client = new T_Client(new T_Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(Object objIn) {
//this method calls the onProgressUpdate
publishProgress(objIn);
}
});
client.run();
return null;
}
#Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
Log.i(TAG,values.getClass().getName().toString());
}
}
}
When I hit the "Send" button I get this error on the server console which points me to the point where I read the object read from the ObjectInputStream and pass it an instance of the Message class but I can't understand what the problem is. I also noticed that it shows this "in.neverhide.connect" which is the package name of the project for my android client
java.lang.ClassNotFoundException: in.neverhide.connect.Message
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:622)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Objects_WORKING.T_Server.run(T_Server.java:61)
Ok after searching around I found this post and the answer from Akinsola 'mys Tunmise. I've made the Message class into a jar and used it as an external reference in both the client and the server.
I am working on a project where I send supposedly press a button on a webpage and it then executes a command in java. What I'm looking for is something like this. Say if I pressed a button and then it sends a command to the minecraft server to reload plugins. How would I go achieving this? Thanks
When you have to comunicate between different applications you will problably need a bridge. In your case I'd suggest to use Minecraft's RCON service (must be enabled in the confingiration) or a plugin that do something similar, like Websend.
Websend code is actually available on Github if you would like to know how the plugin work.
Connection between PHP and Java through sockets
Step 1:
Create a java server
I have created a nice API for these situations. you can use them if you would like:
ChatServer
all you need to do is create a new instance of this class
package com.weebly.foxgenesis.src;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.io.*;
public final class ChatServer implements Runnable
{
private final int CLIENTMAXIMUM;
private ChatServerThread clients[];
private ServerSocket server = null;
private Thread thread = null;
private int clientCount = 0;
private final ServerReciever output;
private List<ConnectHandler> connectHandlers = new ArrayList<ConnectHandler>();
private List<QuitHandler> quitHandlers = new ArrayList<QuitHandler>();
/**
* creates a new ChatServer for connection between clients
* #param a ServerReciever implementing class
*/
public ChatServer(ServerReciever a)
{
CLIENTMAXIMUM = a.getMaximunClients();
output = a;
clients = new ChatServerThread[CLIENTMAXIMUM];
try
{
server = new ServerSocket();
server.bind(new InetSocketAddress(output.getHost(), output.getPort()));
log(server);
start();
}
catch(IOException ioe)
{
error("Can not bind to port " + a.getPort() + ": " + ioe.getMessage());
}
}
/**
* Force the Server to handle a msg
*/
public void add(String text)
{
output.handle(text);
}
/**
* Force the Server to handle an error
*/
public void error(String text)
{
output.handleError(text);
}
/**
* Log to the server
*/
public void log(Object text)
{
output.handleLog(text);
}
/**
* send a message to a specific client
* #param ID ID of client
* #param msg
*/
public void send(int ID, String msg)
{
clients[findClient(ID)].send(msg);
add(msg);
}
/**
* Called by runnable
*/
public void run()
{
while (thread != null)
{
try
{
if(clientCount != CLIENTMAXIMUM){
log("Waiting for a client ...");
addThread(server.accept());
}
}
catch(IOException ioe)
{
error("Server accept error: " + ioe);
stop();
}
}
}
private void start()
{
if (thread == null)
{
thread = new Thread(this);
thread.start();
}
}
/**
* Stops the server
*/
#SuppressWarnings("deprecation")
public void stop()
{
if (thread != null)
{
thread.stop();
thread = null;
}
}
private int findClient(int ID)
{
for (int i = 0; i < clientCount; i++)
if (clients[i].getID() == ID)
return i;
return -1;
}
/**
* sends a message to a
* #param ID
* #param input
*/
public synchronized void handle(int ID, String input)
{
StringTokenizer t = new StringTokenizer(input);
String[] arg = new String[t.countTokens()];
for(int i=0; t.hasMoreElements(); i++)
arg[i] = t.nextToken(",");
if(arg[0] == "new")
switch(input)
{
case".bye":
{
clients[findClient(ID)].send(".bye");
remove(ID);
break;
}
default:
{
for (int i = 0; i < clientCount; i++)
clients[i].send(input);
break;
}
}
}
/**
* sends a message to all clients
* #param input message to send
*/
public void sendAll(String input)
{
for (int i = 0; i < clientCount; i++)
clients[i].send(input);
}
/**
* remove a selected ID
* #param ID ID of client
*/
#SuppressWarnings("deprecation")
public synchronized void remove(int ID)
{
int pos = findClient(ID);
if (pos >= 0)
{
ChatServerThread toTerminate = clients[pos];
log("Removing client thread " + ID + " at " + pos);
if (pos < clientCount-1)
for (int i = pos+1; i < clientCount; i++)
clients[i-1] = clients[i];
clientCount--;
QuitEvent e = new QuitEvent(toTerminate.getID());
e.setGameBreaking(true);
for(QuitHandler a: quitHandlers)
a.quit(e);
try
{
toTerminate.close(); }
catch(IOException ioe)
{
error("Error closing thread: " + ioe);
}
toTerminate.stop();
}
}
private void addThread(Socket socket)
{
if (clientCount < clients.length)
{
log("Client accepted: " + socket);
clients[clientCount] = new ChatServerThread(this, socket);
try
{
clients[clientCount].open();
clients[clientCount].start();
ClientConnectEvent e = new ClientConnectEvent(clients[clientCount],clients[clientCount].getID());
clientCount++;
for(ConnectHandler a: connectHandlers)
a.connect(e);
}
catch(IOException ioe)
{
error("Error opening thread: " + ioe);
}
}
else
error("Client refused: maximum " + clients.length + " reached.");
}
public String toString()
{
return "ChatServer{;host=" + output.getHost() + ";port=" + output.getPort() + ";clients=" + clientCount + ";}";
}
public int getAmountOfClients()
{
return clientCount;
}
public void addConnectHandler(ConnectHandler handler)
{
connectHandlers.add(handler);
}
public void removeConnectHandler(ConnectHandler handler)
{
connectHandlers.remove(handler);
}
public int getMaxClients()
{
return CLIENTMAXIMUM;
}
public void addQuitHandler(QuitHandler quitHandler)
{
quitHandlers.add(quitHandler);
}
public void removeQuitHandler(QuitHandler quithandler)
{
quitHandlers.remove(quithandler);
}
}
ChatServerThread
Used by the ChatServer as client connections
package com.weebly.foxgenesis.src;
import java.net.*;
import java.io.*;
public final class ChatServerThread extends Thread
{
private ChatServer server = null;
private Socket socket = null;
private int ID = -1;
private DataInputStream streamIn = null;
private DataOutputStream streamOut = null;
public ChatServerThread(ChatServer server, Socket socket)
{
super();
this.server = server;
this.socket = socket;
this.ID = socket.getPort();
}
#SuppressWarnings("deprecation")
public void send(String msg)
{
try
{
streamOut.writeUTF(msg);
streamOut.flush();
}
catch(IOException ioe)
{
server.error(ID + " ERROR sending: " + ioe.getMessage());
server.remove(ID);
stop();
}
}
public int getID()
{
return ID;
}
#SuppressWarnings("deprecation")
#Override
public void run()
{
server.log("Server Thread " + ID + " running.");
while (true)
{
try
{
server.handle(ID, streamIn.readUTF());
}
catch(IOException ioe)
{
server.error(ID + " ERROR reading: " + ioe.getMessage());
server.remove(ID);
stop();
}
}
}
public void open() throws IOException
{
streamIn = new DataInputStream(new
BufferedInputStream(socket.getInputStream()));
streamOut = new DataOutputStream(new
BufferedOutputStream(socket.getOutputStream()));
}
public void close() throws IOException
{
if (socket != null) socket.close();
if (streamIn != null) streamIn.close();
if (streamOut != null) streamOut.close();
}
}
ClientConnectEvent
package com.weebly.foxgenesis.src;
public class ClientConnectEvent extends ConnectionEvent
{
private final ChatServerThread client;
public ClientConnectEvent(ChatServerThread client, int clientID)
{
super(clientID);
this.client = client;
}
public ChatServerThread getClient()
{
return client;
}
#Override
public boolean isConnectionBreaking(){return false;}
}
ConnectHandler
package com.weebly.foxgenesis.src;
public interface ConnectHandler
{
public void connect(ClientConnectEvent e);
}
ClientQuitEvent
package com.weebly.foxgenesis.src;
public class ClientQuitEvent extends ConnectionEvent
{
public ClientQuitEvent(int clientID)
{
super(clientID);
}
#Override
public boolean isConnectionBreaking()
{
return true;
}
}
QuitHandler
package com.weebly.foxgenesis.src;
public interface QuitHandler
{
public void quit(ClientQuitEvent e);
}
ServerReciever
package com.weebly.foxgenesis.src;
public interface ServerReciever
{
public void handle(String msg);
public void handleError(String msg);
public int getPort();
public int getMaximunClients();
public void handleLog(Object text);
public String getHost();
}
ConnectionEvent
package com.weebly.foxgenesis.src;
public abstract class ConnectionEvent
{
public abstract boolean isConnectionBreaking();
private int clientID;
public ConnectionEvent(int clientID)
{
this.clientID = clientID;
}
public int getClientID()
{
return clientID;
}
}
Step 2:
Connect Server to Bukkit
i have provided an example on how to connect the server to bukkit by making a new plugin.
public class MyPlugin extends JavaPlugin
{
#Override
public void onEnable()
{
ChatServer server = new ChatServer(new ServerReciever()
{
#Override
public void handle(String msg){handleMsg(msg);}
#Override
public void handleError(String msg){handleErr(msg);}
#Override
public int getPort(){return 25567}
#Override
public int getMaximunClients(){return 100;}
#Override
public void handleLog(Object text){log(text);}
#Override
public String getHost(){return "localhost";}
}
}
public void handleLog(Object text)
{
System.out.println(text);
}
public void handelErr(String msg)
{
System.err.println(msg);
}
public void handleMsg(String msg)
{
if(msg.equalsIgnoreCase("reload"))
Bukkit.reloadOrSomething(); //i don't know the void off the top of my head
}
}
Step 3:
Port Forward
if you don't know what that is go ahead and google it. there are some great tutorials online. you want to port forward the port that you set in the code.
Step 4:
Send a message to the Server
i do not know PHP but all you need to do is send a UTF-8 Encoded message to the server's ip on the port that you hard coded above.
Step 5:
ENJOY!
I want to save and store simple mail objects via serializing, but I get always an error and I can't find where it is.
package sotring;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import com.sun.org.apache.bcel.internal.generic.INEG;
public class storeing {
public static void storeMail(Message[] mail){
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("mail.ser"));
out.writeObject(mail);
out.flush();
out.close();
} catch (IOException e) {
}
}
public static Message[] getStoredMails(){
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("mail.ser"));
Message[] array = (Message[]) in.readObject() ;
for (int i=0; i< array.length;i++)
System.out.println("EMail von:"+ array[i].getSender() + " an " + array[i].getReceiver()+ " Emailbetreff: "+ array[i].getBetreff() + " Inhalt: " + array[i].getContent());
System.out.println("Size: "+array.length); //return array;
in.close();
return array;
}
catch(IOException ex)
{
ex.printStackTrace();
return null;
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
return null;
}
}
public static void main(String[] args) {
User user1 = new User("User1", "geheim");
User user2 = new User("User2", "geheim");
Message email1 = new Message(user1.getName(), user2.getName(), "Test", "Fooobaaaar");
Message email2 = new Message(user1.getName(), user2.getName(), "Test2", "Woohoo");
Message email3 = new Message(user1.getName(), user2.getName(), "Test3", "Okay =) ");
Message [] mails = {email1, email2, email3};
storeMail(mails);
Message[] restored = getStoredMails();;
}
}
Here are the user and message class
public class Message implements Serializable{
static final long serialVersionUID = -1L;
private String receiver; //Empfänger
private String sender; //Absender
private String Betreff;
private String content;
private String timestamp;
private String getDateTime() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
return dateFormat.format(date);
}
Message (String receiver, String sender, String Betreff, String content) {
this.Betreff= Betreff;
this.receiver = receiver;
this.sender = sender;
this.content = content;
this.timestamp = getDateTime();
}
Message() { // Just for loaded msg
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getBetreff() {
return Betreff;
}
public void setBetreff(String betreff) {
Betreff = betreff;
}
public String getContent() {
return content;
}
public String getTime() {
return timestamp;
}
public void setContent(String content) {
this.content = content;
}
}
public class User implements Serializable{
static final long serialVersionUID = -1L;
private String username; //unique Username
private String ipadress; //changes everytime
private String password; //Password
private int unreadMsg; //Unread Messages
private static int usercount;
private boolean online;
public String getName(){
return username;
}
public boolean Status() {
return online;
}
public void setOnline() {
this.online = true;
}
public void setOffline() {
this.online = false;
}
User(String username,String password){
if (true){
this.username = username;
this.password = password;
usercount++;
} else System.out.print("Username not availiable");
}
public void changePassword(String newpassword){
password = newpassword;
}
public void setIP(String newip){
ipadress = newip;
}
public String getIP(){
if (ipadress.length() >= 7){
return ipadress;
} else return "ip address not set.";
}
public int getUnreadMsg() {
return unreadMsg;
}
}
Here is the exception:
exception in thread "main" java.lang.Error: Unresolved compilation problem:
This method must return a result of type Message[]
at sotring.storeing.getStoredMails(storeing.java:22)
at sotring.storeing.main(storeing.java:57)
THANK YOU FOR YOUR HELP!!!!!!!!!!!
The catch clauses need to return something.
public static Message[] getStoredMails(){
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("mail.ser"));
Message[] array = (Message[]) in.readObject() ;
System.out.println("Size: "+array.length); //return array;
in.close();
return array;
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}
return null; //fix
}
If an exception occurs, you never get to the return statement in getStoredMails. You need to either throw the exception you catch (possibly wrapping it in another more descriptive exception) or just return null at the end of the method. It really depends on what you want to do if there's an error.
Oh, and your in.close() should be in a finally block. Otherwise, it is possible that you could read the data fine but then throw it away if you can't close the stream.
On a different note, have you considered a third-party serializer library?
I'm using Simple right now for a project, and it seems to do stuff just fine with very little effort.
in the exception handling blocks of the getStoredMails method you do not return anything.
Suggested modification:
public static Message[] getStoredMails(){
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("mail.ser"));
Message[] array = (Message[]) in.readObject() ;
System.out.println("Size: "+array.length); //return array;
in.close();
return array;
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}
return null;
}
I modified the source. I added "return null" in exception and the for loop the output in the function. And the function gives me the right output but then throws it the exception.