I am experiencing an error which I am at a loss to explain. I feel like I'm so close but I just can't seem to get a connection.
I have setup two RMI server objects on a remote server and I want to connect to and use these. I am able to connect to the RMIRegistry on the server on port 1099 and with the call Registry.list() I get the correct names of the stubs which are setup on the server.
Now for my code...
Server object 1
Registry registry = null;
try {
registry = LocateRegistry.createRegistry(1099);
} catch (RemoteException e){
System.out.println("Registry already exists - connecting...");
try {
registry = LocateRegistry.getRegistry(1099);
String[] objects = registry.list();
for (int n=0; n<objects.length; n++){
System.out.println(objects[n]);
}
} catch (RemoteException ex) {
ex.printStackTrace();
System.out.println("RMI registry connection fail.");
System.exit(1);
}
}
BioBingoLogic bb = null;
bb = new BioBingoLogic();
BioBingoInterface bbStub = null;
try {
bbStub = (BioBingoInterface)
UnicastRemoteObject.exportObject(bb, 9753);
} catch (RemoteException e){
e.printStackTrace();
System.out.println("RemoteServer export fail.");
System.exit(1);
}
try {
registry.rebind("BioBingoServer", bbStub);
} catch (RemoteException e){
e.printStackTrace();
System.out.println("Registry rebind fail.");
System.exit(1);
}
Server object 2
Completely the same as Server object 1 only exported on port 9754 and called "DatabaseServer".
Output
My output from these two objects is in the following picture:
Output from running the two server objects.
Client side
The server objects work as I expect them to. It is the Client which doesn't seem to be able to connect to the individual server objects.
System.out.println("Creating RMI Registry stub.");
Registry remoteRegistry = null;
try {
remoteRegistry = LocateRegistry.getRegistry("biobingo", 1099);
String[] objects = remoteRegistry.list();
System.out.println("\nObjects in stub:");
for (int n = 0; n < objects.length; n++) {
System.out.println(objects[n]
}
System.out.println();
System.out.println("Connecting to BioBingoServer object.");
try {
game = (BioBingoInterface) remoteRegistry.lookup("BioBingoServer");
db = (DatabaseInterface) remoteRegistry.lookup("DatabaseServer");
} catch (Exception e) {
e.printStackTrace();
System.out.println("Stub not found.");
System.exit(1);
}
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("Registry not found.");
System.exit(1);
}
System.out.println("Connected to BioBingoServer.");
System.out.println("Connected to DatabaseServer");
biobingo is the IP of the remote server registered with the alias in my hosts file.
Output
This is where the problem arises....
I get the output in the following picture:
Output from client side application
It should be understood from the picture, that I never get an exception of any kind. It just hangs on the call Registry.lookup() until it, I suppose, gets a timeout from the server and executes the next part of the client code - calls to the server object then throws a RemoteException.
It should be noted that the remote server is behind a NAT, however, the NAT and its firewall is setup to allow all incoming TCP traffic, from all IP's, on all the specified ports; 1099 + 9753 + 9754.
I have also verified that the ports are indeed open with a port scanner.
This is where I am at a loss...
Any suggestions to what is preventing me from connecting to the server objects, when I am entirely able to connect to the RMIRegistry?
Any help is greatly appreciated - thank you!
---------------------------------------------
EDIT
---------------------------------------------
I tried running the server objects and client with the java vm option:
-Dsun.rmi.transport.tcp.logLevel=VERBOSE
The following picture shows the output and includes description of the flow and where the possible error occurs:
output with java vm option.
Client output
No output, just a 3 minute delay on Registry.lookup(). Afterwards the following code is executed and then on function calls to the RMI stub there’s a 3 minute delay followed by a ConnectException saying *connection timed out to 10.230.56.71` (which is the local IP of the server, although I’m connecting to it’s global IP - so it seems that my call does find it’s way to the NAT which the server is behind).
Server output
Nothing, really.
Related
I have a client that I want to try to continuously connect to a server until a connection is established (i.e. until I start the server).
clientSocket = new Socket();
while (!clientSocket.isConnected()) {
try {
clientSocket.connect(new InetSocketAddress(serverAddress, serverPort));
} catch (IOException e) {
e.printStackTrace();
}
// sleep prevents a billion SocketExceptions from being printed,
// and hopefully stops the server from thinking it's getting DOS'd
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
After the first attempt, I get a ConnectionException; expected, since there is nothing to connect to. After that, however, I start getting SocketException: Socket closed which doesn't make sense to me since clientSocket.isClosed() always returns false, before and after the connect() call.
How should I change my code to get the functionality I need?
You can't reconnect a Socket, even if the connect attempt failed. You have to close it and create a new one.
I have an FTP server, I am trying to upload a file
in FTPClient.openDataConnection(), I get down to the line
if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) {
return null;
}
The command is "STOR" and arg is "edf0864d-1651-43b2-8453-d160bf9d0742" (the name of the file I want to store)
The server log looks like:
PORT 86,185,26,230,213,101
200 Port command successful
STOR edf0864d-1651-43b2-8453-d160bf9d0742
150 Opening data channel for file upload to server of "/edf0864d-1651-43b2-8453-d160bf9d0742"
(Up to here after calling sendCommand)
PORT 86,185,26,230,213,102
200 Port command successful
From the logs the response code is 150, but sendCommand returns a response code of 200
Other potentially important information
I'm using filezilla server
The server works most of the time, with the exact same code. The initial upload of the file works fine, then when I choose another file to overwrite the first upload, this happens.
Following on from that, there's another file with the same name, but I haven't had trouble with that before.
The server is configured for passive connections as far as I can tell, it doesn't shout at me when I start it up like it used to, but the PASV command produces a 421 could not create socket error. I'm using ACTIVE_LOCAL mode
I'm using apache commons net 3.6
Let me know if there's any more information that can help
This is the relevant parts of the java:
FTPClient ftp = new FTPClient();
String server = <server ip>;
int port = 21;
String username = <username>;
String password = <password>;
try{
ftp.connect(server, port);
}
catch(SocketException e){
throw new FTPCouldNotConnectException("Threw SocketException during connection", e);
}
catch(IOException e){
throw new FTPCouldNotConnectException("Threw IOException during connection", e);
}
int reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)){
try{
ftp.disconnect();
throw new FTPCouldNotConnectException("Reply Code: " + reply + ", Could not connect");
}
catch(IOException e){
throw new FTPCouldNotConnectException(
"Threw IOException during disconnection after failing to connect with reply code: " + reply,
e);
}
}
else{
try{
if(ftp.login(username, password)){
LOGGER.info("Successfully logged in to ftp server");
ftp.setFileTransferMode(org.apache.commons.net.ftp.FTP.STREAM_TRANSFER_MODE);
ftp.setFileStructure(org.apache.commons.net.ftp.FTP.FILE_STRUCTURE);
ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
ftp.enterLocalActiveMode();
}
else{
LOGGER.warn("Failed to log in to ftp server");
}
}
catch(IOException e){
throw new FTPCouldNotConnectException("Failed to log in to server, threw ioexception", e);
}
}
try{
ftp.storeFile("edf0864d-1651-43b2-8453-d160bf9d0742", new FileInputStream("test.jpg"));
}
catch(IOException e){
LOGGER.error("java.io.IOException caught", e);
}
I found the answer based on the fact that the first call of the code worked fine, but the second failed.
In the java code, I hadn't called FTPClient.completePendingCommand(), which as The docs say, causes subsequent calls to behave unexpectedly.
ill try to explain my setting.
Setting:
i run 1 "server"(note: not rmi server) who is always up.
When i run 1 client, the client creates an rmi host like so:
String bindLocation = "//localhost/ntn";
try {
registry = LocateRegistry.createRegistry(1099);
Naming.bind(bindLocation, ntn);
} catch (MalformedURLException | AlreadyBoundException e) {}
And the server starts acting as a RMI client like so:
try {
name = "//localhost/ntn";
ntnI = null;
ntnI = (NodeToNodeInterface) Naming.lookup(name);
ntnI.serverAnswer(k);
k++;
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}
This all works. But after that the client has received the "server answer" it unbinds like so:
try {
Naming.unbind(bindLocation);
UnicastRemoteObject.unexportObject(registry,true);
} catch (NotBoundException e) {}
Now if i Open a seccond client(same code as client 1) it again start to act as a RMI server on the same name and port. if this is set up de same function runs on the server and gives the following error:
java.rmi.NoSuchObjectException: no such object in table
wich points to the line:
ntnI = (NodeToNodeInterface) Naming.lookup(name);
How do i reinitialise it? or how to fix this?
Normally the RMI server is perfectly setup before the server(RMIclient) uses the serverAnswer function.(and it works teh first time)
Don't unexport the registry, and don't create it when you bind. Create it first and leave it there for the life of the JVM. Otherwise there is nothing for Naming.lookup() to talk to.
I try to check if port 80 is available using the following method :
Sockets: Discover port availability using Java
I have a Java application that checks if port 80 is available, if so, it runs a small web server listening on port 80. It works great to detect if another Java application listens on port 80, e.g. if I run my application two times, the second instance will correctly tell me that the port 80 is being used.
The problem is that I have WAMP running and listening on port 80, and that if I run my Java application after I started WAMP, it won't tell me that the port 80 is busy. It seems that it only tells me if another Java application uses the port 80.
That goes beyond my understanding ... any help is greatly appreciated!
Code snippet:
int port = 80;
if(!Connection.isPortAvailable(port)) {
logger.info("Port " + port + " is already in use");
}
// in Connection class
public static boolean isPortAvailable(int port) {
ServerSocket ss = null;
DatagramSocket ds = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
ds = new DatagramSocket(port);
ds.setReuseAddress(true);
return true;
} catch (IOException e) {
} finally {
if (ds != null) {
ds.close();
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
/* should not be thrown */
}
}
}
return false;
}
The correct answer to all questions of this nature is to try to use it and catch the exception. Not try to see if it's available and then try to use it and still have to handle the exception, which has several obvious problems:
There is a timing window between 'see' and 'try' during which the situation can change (both ways).
You still have to catch failures in the 'use' part anyway.
It is basically just trying to predict the future. This is supposed to be computer science, not fortune-telling.
This applies to most values of 'it', including network ports, files, any resource really.
I was able to reproduce your problem by running WampServer (verified that it was running by visiting localhost:80) and running a minimal java program given your example code.
The code in the try block did not throw an exception when WampServer was running. However, modify the first few lines of the try block like this
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));
and isPortAvailable will properly detect when WampServer is running and when it is not. Using "0.0.0.0" instead of "127.0.0.1" didn't work with WampServer, but did properly detect when IIS was running. You can check both by closing the first socket
ss = new ServerSocket();
ss.bind(new InetSocketAddress("0.0.0.0", port));
ss.close();
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));
I am testing a chat application for number of users. So what I am trying is as follows:
I am trying to run my chat application by login for chat for only one user for 1000 times in for loop. here is my part of code .
public void LoginChatConnect() {
try {
// while(true){
for(int i=0;i<1000;i++){
System.out.println("inside loginChatLogin");
String userId = "Rahul";
String password = "rahul";
sockChatListen = new Socket("localhost", 5004);
// /sockChatListen.
dosChatListen = new DataOutputStream(
sockChatListen.getOutputStream());
disChatListen = new DataInputStream(sockChatListen.getInputStream());
dosChatListen.writeUTF(userId);
dosChatListen.writeUTF(password);
// System.out.println(dosChatListen.toString());
dosChatListen.flush();
// sockChatListen.close();
boolean b = sockChatListen.isClosed();
System.out.println("connection open**********************" + b);
sockChatListen.close();
System.out.println("connection closed**********************" + b);
count++;
System.out.println("count" + count);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In above code I am just trying to login for only one user for 1000 times. But after certain login it is giving me this socket error.
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
Here I am trying to create a connection with a single port 5004. why I am getting error after 100+ successful connections(login).?
How should I recover this problem?
Any suggestions will be helpful.
What I understand from your post is that you want to simulate 1000 users logging to the chat server concurrently. I believe you are trying to test the load on your chat server.
However, from your code, I see that you are establishing and closing the socket connection every time in the loop. This is similar to 1000 users waiting in a queue and attempting to login to the server one after the other. This does not simulate the concurrent load but a 1000 sequential calls to the server and would not be appropriate to load test your server.
My comments are based on the above stated understanding. Please calrify if this is not the case.
Regarding the exception you get, I have no idea why it should not work after 100+ attempts. May be you need to check your server side code to figure out the problem.