RMI chat over Internet - java

I managed to make the client send objects to the server and the server does reply correctly but only to the client who sent the object, I had to forward ports on the server side and allowed port connections on the server side, now I can't seem to send a reply/message to a specific client and always get a connection refused error, meddling with portforwardind/firewall on the client side is not possible since anyone should be able to use the chat(the client must stay a client and not become a server). Any ideas how to make this work ? I heard about http tunneling or rmi proxy but how does it work code-wise ?
here's my main code on the client side :
public class Main {
public static void main(String [] args) {
String input;
Scanner in = new Scanner(System.in);
input = in.nextLine();
try
{
Message b =(Message) Naming.lookup("//xx.xx.xx.xx:1099/Message");
Client c=new Client(input);
UnicastRemoteObject.exportObject(c, 1100);
b.addUser(c);
while(true)
{
input = in.nextLine();
if(input.contentEquals("deconnection"))
{
b.exit();
break;
}
else if(input.startsWith(">"))
{
b.broadcast(c,"test");
}
}
in.close();
}
catch (NotBoundException re) { System.out.println(re) ; }
catch (RemoteException re) { System.out.println(re) ; }
catch (MalformedURLException e) { System.out.println(e) ; }
}
}
on the server side :
public class Serveur
{
public static void main(String [] args) {
try {
MessageImpl objLocal = new MessageImpl();
Naming.rebind("rmi://localhost:"+1099+"/Message" , UnicastRemoteObject.exportObject(objLocal, 1100)) ;
System.out.println("Serveur pret");
}
catch (RemoteException re) { System.out.println(re) ; }
catch (MalformedURLException e) { System.out.println(e) ; }
}
}
with the MessageImpl.java where the clientlist is found :
public class MessageImpl
implements Message {
public Vector<ClientInterface> clientlist;
public MessageImpl () throws RemoteException {super();listec=new Vector<ClientInterface>();};
public String envoiMessage() throws RemoteException {
return( "message test" );
}
public boolean isNew(ClientInterface c) throws RemoteException
{
return false;
}
public String test() throws RemoteException
{
System.out.println("re");
return "test";
}
public void addUser(ClientInterface c) throws RemoteException
{
test();
clientlist.add(c);
}
public void broadcast(ClientInterface c,String message) throws RemoteException
{
int i;
for(i=0;i<clientlist.size();i++)
{
if(clientlist.elementAt(i).getUsername().equals(c.getUsername()))
{}
else
{
clientlist.elementAt(i).getMessage(c.getUsername()+" : "+message);
}
}
}
public String exit() throws RemoteException
{
try{
return "exiting messenger";
}
catch(Exception e){return "erreur deconnection";}
}
}

If 'meddling' with the client firewall isn't possible, your system is unimplementable as designed. You would have to use polling instead of callbacks on the client side.

Related

java rmi notboundexception

I'm trying to develop. My RMI code Initiation that had Server/Client locally for learning purposes. The server part had two interfaces Echo & Sum implemented in the serverRMI and I tried to call from the client side but got this error. Does anyone have any ideas how I can resolve this?
Server.java
public class Server {
public static void main(String[] args) {
try {
MyServerRMI server = new MyServerRMI();
LocateRegistry.createRegistry(1099);
Naming.rebind("rmi://localhost:1099/Server", server);
System.out.println("Server is ready for clients to connect");
} catch (Exception e) {
System.out.println("Server failed: " + e);
}
}
}
MyServerRMI
public class MyServerRMI extends UnicastRemoteObject implements EchoInterface, SumInterface {
public MyServerRMI() throws RemoteException {
super();
}
public String echo(String s) throws RemoteException {
return s;
}
public int sum(int a, int b) throws RemoteException {
return a + b;
}
}
MyClientRMI
public class MyClientRMI {
public static void main(String[] args) {
try {
EchoInterface objetEcho = (EchoInterface) Naming.lookup("rmi://localhost:1099/server");
SumInterface objetSum = (SumInterface) Naming.lookup("rmi://localhost:1099/server");
System.out.println("Echo: " + objetEcho.echo("Hello World from RMI server"));
System.out.println("Sum: " + objetSum.sum(5, 10));
} catch (Exception e) {
System.out.println("Client failed: " + e);
}
}
}
You have not associated the bindings in the client. To do that, you should use:
Registry registry = LocateRegistry.getRegistry(host);
or
Registry registry = LocateRegistry.getRegistry(port);
and then
EchoInterface objetEcho = (EchoInterface) registry.lookup("rmi://localhost:1099/server");
SumInterface objetSum = (SumInterface) registry.lookup("rmi://localhost:1099/server");
also, please use
e.printStackTrace();
instead of just printing e, as the stack trace provides a lot more information.

Thrift Async Client will not stop

I wonder why without the code remarked as 1, even the result is not null, the application keeps running and never stop, and the code remarked as 2 doesn't print the expected result.
But with the code remarked as 1, the application finishes when the result is not null,and prints the code which remarked as 2.
AsyncMethodCallback
private Object response=null;
public Object getResponse() {
return response;
}
#Override
public void onComplete(Object response) {
this.response=response;
}
#Override
public void onError(Exception exception) {
exception.printStackTrace();
}
Async Server
public static void main(String[] args) {
try {
TNonblockingServerSocket serverSocket=new TNonblockingServerSocket(10005);
Hello.Processor<Hello.Iface> processor=new Hello.Processor<>(new HelloServiceImpl());
TNonblockingServer.Args serverArgs=new TNonblockingServer.Args(serverSocket);
TProtocolFactory factory=new TBinaryProtocol.Factory();
serverArgs.transportFactory(new TFramedTransport.Factory());
serverArgs.processor(processor);
serverArgs.protocolFactory(factory);
TServer server=new TNonblockingServer(serverArgs);
System.out.println("server start....");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
Async Client
public static void main(String[] args) {
try {
TAsyncClientManager clientManager=new TAsyncClientManager();
TNonblockingSocket socket=new TNonblockingSocket("localhost",10005);
TProtocolFactory protocolFactory=new TBinaryProtocol.Factory();
Hello.AsyncClient asyncClient=new Hello.AsyncClient(protocolFactory,clientManager,socket);
System.out.println("Client calls....");
MethodCallback<Integer> methodCallback=new MethodCallback<>();
asyncClient.helloInt(14,methodCallback);
Object result=methodCallback.getResponse();
while (result==null){
result=methodCallback.getResponse();
// System.out.println("result is "+result); //1
}
System.out.println(result); //2
} catch (IOException | TException e) {
e.printStackTrace();
}
}

Sending a String through socket. Server not receiving it

I've been struggling lately to find a way to deliver strings through a socket file. I'm planning to create a remote tool(client) to execute things based on the received message(server).
I've searched answers for my problem on google and i found some things and managed to understand things but I also got some problems (i'm new to programming, not yet in college).
I would appreciate any help in this matter
SocketService.java ---- class file = serverside
package socket;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
public class ServiceSocket {
static ServerSocket myService;
static Socket thesocket;
static Thread socketThread;
public static boolean socketRunning;
public static DataInputStream socketMessage;
public static void initialise(String localhost, int portNumber ){
// make a server socket//////
try {
myService = new ServerSocket(portNumber);
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
//////////////////////////////
}
public static void deploySocket(){
socketThread = new Thread() {
public void run(){
// making connection
System.out.println("VVaiting for connection...");
try {
thesocket = myService.accept();
System.out.println("Connection made");
socketRunning = true;
} catch (IOException e) {
e.printStackTrace();
}
////////////////////////////////////
try {
StartBrain();
} catch (IOException e1) {
e1.printStackTrace();
}
if(socketRunning = false) {
try {
thesocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
socketThread.start();
}
public static String getSocketMessage() throws IOException {
try {
socketMessage = new DataInputStream(thesocket.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
boolean looprunning = true;
String message = null;
System.out.println("entering loop");
do {
try {
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
} catch (EOFException e) {
}
}while(looprunning);
System.out.println("Message received from UTF: " + message);
System.out.println("loop exited vvith message");
if(message == null) {
message = "no message";
}
return message;
}
public static void StartBrain() throws IOException {
System.out.println("socket brain started");
String BrainMessage = getSocketMessage();
if(BrainMessage == "command") {
System.out.println("Command EXECUTED HAHA");
} else if(BrainMessage == "taskschedule") {
System.out.println("task scheduled");
} else {
System.out.println("no command received");
}
}
Main.java ----- class file = serverside
package main;
import socket.ServiceSocket;
public class Main {
public static void main(String[] args) {
ServiceSocket.initialise("localhost", 3535);
ServiceSocket.deploySocket();
}
}
}
Main.java = CLIENT
package mainPackage;
import java.io.*;
import java.net.*;
import java.util.concurrent.TimeUnit;
public class Main {
private static Socket clientSocket;
public static void sendMessage(String message) throws IOException, InterruptedException {
DataOutputStream dOut = new DataOutputStream(Main.clientSocket.getOutputStream());
dOut.writeUTF(message);
dOut.flush();
dOut.close();
}
public static void main(String[] args) throws Exception {
// String modifiedSentence;
clientSocket = new Socket("localhost", 3535);
System.out.println("Initializing");
sendMessage("command");
boolean running = true;
while(running) {
TimeUnit.SECONDS.sleep(3);
sendMessage("taskschedule");
}
clientSocket.close();
}
}
main problem
do {
try {
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
} catch (EOFException e) {
}
}while(looprunning);
it doesn't read the string/UTF
It does read it, here:
while (socketMessage.readUTF() != null) {
and then throws it away as you're not assigning the return-value to a variable, and then tries to read another one, here:
message = socketMessage.readUTF();
but the one (first) message you send is already gone.
You have problem in
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
First call to method readUTF() will block thread and read UTF string from socket, but you discard this value and try read string second time.
If you replace socketMessage.readUTF() != null with looprunning server will log this messages:
VVaiting for connection...
Connection made
socket brain started
entering loop
Message received from UTF: command
loop exited vvith message
no command received
P.S.
Command is not recognized because use compare objects (string is object) with ==, but you must use equals.
public static void StartBrain() throws IOException {
System.out.println("socket brain started");
String BrainMessage = getSocketMessage();
if (BrainMessage.equals("command")) {
System.out.println("Command EXECUTED HAHA");
} else if (BrainMessage.equals("taskschedule")) {
System.out.println("task scheduled");
} else {
System.out.println("no command received");
}
}
Server log:
VVaiting for connection...
Connection made
socket brain started
entering loop
Message received from UTF: command
loop exited vvith message
Command EXECUTED HAHA

Java Socket Handling Clients Disconnecting [duplicate]

This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 7 years ago.
i am trying to make a chat program. The problem i am having is that my loop in the EchoThread always thinks that the connection is true. I have tried to use if(s.isConnected() == false) but that didn't work also i tried to do if(s.isClosed() == true) if you can help thank you in advance. Here is my code
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class server {
public ObjectInputStream input;
public ServerSocket server;
public Socket s;
public ObjectOutputStream output;
public ArrayList<ObjectOutputStream> outputs = new ArrayList<ObjectOutputStream>();
public ArrayList<Socket> users = new ArrayList<Socket>();
public class Accept implements Runnable {
public void run() {
try {
server = new ServerSocket(55555, 100);
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
s = server.accept();
new EchoThread(s).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class EchoThread extends Thread {
private Socket s1;
public EchoThread(Socket s) throws IOException {
this.s1 = s;
}
public void run() {
users.add(s1);
try {
outputs.add(new ObjectOutputStream(s1.getOutputStream()));
newUser();
} catch (IOException e) {
System.out.println("Error 2");
}
while(s1.isConnected() == true) {
// loops until socket looses connection
}
System.out.println("Disconnected");
}
}
public class check implements Runnable {
public void run() {
}
}
public void newUser() {
try {
for(ObjectOutputStream o: outputs) {
o.writeObject(s.getInetAddress() + " Connected");
}
} catch (IOException e1) {
System.out.println("Error 21");
}
}
server() throws IOException {
Thread t = new Thread(new Accept());
t.start();
Thread ch = new Thread(new check());
ch.start();
}
public static void main(String[] args) throws IOException {
new server();
}
}
you have to read this, you have to check with the read()method to check if it returns -1.
https://stackoverflow.com/a/10241044/964152
while(s1.isConnected() == true) {
This is not a valid loop. isConnected() is true because you accepted the socket, and it doesn't magically become false afterwards. When the client disconnects, you will get the appropriate end of stream indication from whichever read method you're calling.

Websocket server.run() don't allow followed codes to start

I have the following web-socket server code from (https://github.com/TooTallNate/Java-WebSocket):
public class WebsocketServer extends WebSocketServer {
private static int PORT = 2005;
private Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
System.out.println("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
conns.remove(conn);
System.out.println("Closed connection to " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onMessage(WebSocket conn, String message) {
System.out.println("Received: " + message);
for (WebSocket sock : conns) {
sock.send(messageToSend);
}
}
#Override
public void onError(WebSocket conn, Exception ex) {
ex.printStackTrace();
if (conn != null) {
conns.remove(conn);
// do some thing if required
}
System.out.println("ERROR from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
public static void main(String[] args) throws IOException, InterruptedException {
WebsocketServer server = new WebsocketServer();
server.run();
BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String in = sysin.readLine();
server.sendToAll(in);
if (in.equals("exit")) {
server.stop();
break;
} else if (in.equals("restart")) {
server.stop();
server.start();
break;
}
}
}
public void sendToAll(String text) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
c.send(text);
}
}
}
}
The codes works fine, but all codes that comes after server.run(); won't start/work! that part I need to send messages from Java console to client.
What I am doing wrong?
Note: My client works in JavaScript and can connect to the server
You need to start() Runnable class, not run() it directly
server.start();
instead of
server.run();

Categories

Resources