I'm working on an Android app (Java 8, apache.commons.net.ftp 3.6, Min: API 24/target: API 27) that connects to an FTP server but I'm experiencing a weird problem:
If I connect to one of the public test servers (e.g. speedtest.tele2.net) or the IP address directly (e.g. 10.1.1.123), it works fine.
If I add a typo in a "normal" address on purpose (e.g. sspeedtest.tele2.net), I get the expected java.net.UnknownHostException but if I add a typo to an IP address, no matter if it's in the same network or not (e.g. 10.1.1.223), nothing else happens - no exception, no error, no result, even after the set timeout time has passed.
Code:
FTPClient f = new FTPClient();
f.setDefaultTimeout(5000); //5 seconds
try {
f.connect(url,port);
boolean b = f.login(username,password);
Log.d(TAG,"logged in="+b+", connected="+f.isConnected());
} catch (IOException e) {
e.printStackTrace();
}
I let it run a little bit longer and finally, after 1 minute and 16 seconds an exception was thrown:
W/System.err: java.net.ConnectException: Connection refused
I've tried this multiple times and the exception always seems to be thrown after 1:16.
How do I make this respect the default timeout too? Is there a different one I have to use?
You're setting a timeout for receiving data. The timeout for opening a connection is separate, and set with the setConnectTimeout(int connectTimeout) method:
FTPClient f = new FTPClient();
f.setConnectTimeout(5000); // 5 second timeout to open connection
f.setDefaultTimeout(5000); // 5 second timeout when receiving data
If you get "connection refused" that means the IP address is actually used by some host in the network. If there was nothing at that address, you would get an error more along the lines of "no route to host".
Related
As per ServerSocket(int port, int backlog), backlog indicates maximum length of the queue.
I created a simple server socket, with backlog as 1 using following code ServerSocket serverSocket = new ServerSocket(8001, 1); and my expectation was that when I will try to connect to this server with more than 1 client then I will get connection refused exception.
But when I tried to connect with this server from more than 1 client then I was able to connect even with 3 client in parallel and all were able to communicate with the server.
Am I missing something?
The backlog parameter can be adjusted up or down by the platform. The actual minimum backlog was initially 5 in BSD 4.3 and it is now more like 50 or even 500 on some platforms. There is no API to determine the actual value used.
I have an assigment about port scanning. I am scanning UDP ports of some IP addresses in Java.In my program (assuming everything is OK) I can only find one open UDP port. In the other hands port scanning over "nmap" I get 4 open UDP ports. Can somebody tell me why I can not find more than one ports via Java code?
By the way I can find the true open port in my code.
int startPortRange=1;
int stopPortRange=1024;
InetAddress address = InetAddress.getByName("bigblackbox.cs.binghamton.edu");
int counter=0;
for(int i=startPortRange; i <=stopPortRange; i++)
{
counter++;
try{
byte [] bytes = new byte[128];
DatagramSocket ds = new DatagramSocket();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.setSoTimeout(100);
ds.connect(address, i);
ds.send(dp);
ds.isConnected();
dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
ds.close();
System.out.println("open");
System.out.println(counter);
}
catch(InterruptedIOException e){
//System.out.println("closed");
}
catch(IOException e){
//System.out.println("closed");
}
}
Output of above code is
135 open
When I make same operation in command line using nmap I get more open ports.
I could not upload an image because I am a new user.
Thank you
It is impossible to provide a concrete answer, unless you provide at least:
The source code of your program.
An example of the (incorrect) output that you are getting.
The expected output for the same scenario.
Without this information there is no way for us to tell you what is wrong. For all we know, it could even be a simple case of your program terminating prematurely after finding an open port. Or a case of the open port that was last found overwriting the entries of the previous ones before being displayed.
In any case, it might be worthwhile to investigate what is being sent and received using a network sniffer, such as Wireshark. By comparing an nmap session with a session created by your program, you might be able to spot some significant difference that would help pinpoint the issue.
EDIT:
After having a look at your code and comparing with nmap, it seems that you are mistakenly handling the case of a SocketTimeoutException as a closed port, while it could simply be the port of a server that refuses to answer to the packet that you sent.
EDIT 2:
Here's the full story:
When a port is properly closed, the server sends back an ICMP Destination Unreachable packet with the Port unreachable error code. Java interprets this error to an IOException that you correctly consider to indicate a closed port.
An open port, on the other hand may result into two different responses from the server:
The server sends back a UDP packet, which is received by your program and definitely indicates an open port. DNS servers, for example, often respond with a Format error response. nmap shows these ports are open.
The server ignores your probe packet because it is malformed w.r.t. to the provided service. This results in a network timeout and a SocketTimeoutException in your program.
Unfortunately there is no way to tell whether a network timeout is because an active server ignored a malformed probe packet or because a packet filter cut down the probe. This is why nmap displays ports that time out as open|filtered.
I have encountered a problem of socket communication on linux system, the communication process is like below: client send a message to ask the server to do a compute task, and wait for the result message from server after the task completes.
But the client would hangs up to wait for the result message if the task costs a long time such as about 40 minutes even though from the server side, the result message has been written to the socket to respond to the client, but it could normally receive the result message if the task costs little time, such as one minute. Additionally, this problem only happens on customer environment, the communication process behaves normally in our testing environment.
I have suspected the cause to this problem is the default timeout value of socket is different between customer environment and testing environment, but the follow values are identical on these two environment, and both Client and server.
getSoTimeout:0
getReceiveBufferSize:43690
getSendBufferSize:8192
getSoLinger:-1
getTrafficClass:0
getKeepAlive:false
getTcpNoDelay:false
the codes on CLient are like:
Message msg = null;
ObjectInputStream in = client.getClient().getInputStream();
//if no message readObject() will hang here
while ( true ) {
try {
Object recObject = in.readObject();
System.out.println("Client received msg.");
msg = (Message)recObject;
return msg;
}catch (Exception e) {
e.printStackTrace();
return null;
}
}
the codes on server are like,
ObjectOutputStream socketOutStream = getSocketOutputStream();
try {
MessageJobComplete msgJobComplete = new MessageJobComplete(reportFile, outputFile );
socketOutStream.writeObject(msgJobComplete);
}catch(Exception e) {
e.printStackTrace();
}
in order to solve this problem, i have added the flush and reset method, but the problem still exists:
ObjectOutputStream socketOutStream = getSocketOutputStream();
try {
MessageJobComplete msgJobComplete = new MessageJobComplete(reportFile, outputFile );
socketOutStream.flush();
logger.debug("AbstractJob#reply to the socket");
socketOutStream.writeObject(msgJobComplete);
socketOutStream.reset();
socketOutStream.flush();
logger.debug("AbstractJob#after Flush Reply");
}catch(Exception e) {
e.printStackTrace();
logger.error("Exception when sending MessageJobComplete."+e.getMessage());
}
so do anyone knows what the next steps i should do to solve this problem.
I guess the cause is the environment setting, but I do not know what the environment factors would affect the socket communication?
And the socket using the Tcp/Ip protocal to communicate, the problem is related with the long time task, so what values about tcp would affect the timeout of socket communication?
After my analysis about the logs, i found after the message are written to the socket, there were no exceptions are thrown/caught. But always after 15 minutes, there are exceptions in the objectInputStream.readObject() codes snippet of Server Side which is used to accept the request from client. However, socket.getSoTimeout value is 0, so it is very strange that the a Timed out Exception was thrown.
{2012-01-09 17:44:13,908} ERROR java.net.SocketException: Connection timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:146)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:312)
at sun.security.ssl.InputRecord.read(InputRecord.java:350)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:809)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:766)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:94)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:69)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2265)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2558)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2568)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1314)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
so why the Connection Timed out exceptions are thrown?
This problem is solved. using the tcpdump to capture the messages flows. I have found that while in the application level, ObjectOutputStream.writeObject() method was invoked, in the tcp level, many times [TCP ReTransmission] were found.
So, I concluded that the connection is possibly be dead, although using the netstat -an command the tcp connection state still was ESTABLISHED.
So I wrote a testing application to periodically sent Testing messages as the heart-beating messages from the Server. Then this problem disappeared.
The read() methods of java.io.InputStream are blocking calls., which means they wait "forever" if they are called when there is no data in the stream to read.
This is completely expected behaviour and as per the published contract in javadoc if the server does not respond.
If you want a non-blocking read, use the java.nio.* classes.
I'm trying to connect a socket to an non-existent server, and I really don't understand why an exception is not being raised.
Here is my code:
public class TestSocket extends Activity {
private static final String TAG = "TestSocket";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BasicThread t = new BasicThread();
t.start();
}
class BasicThread extends Thread {
#Override
public void run() {
Log.d(TAG, "Before");
try {
new Socket("42.42.42.42", 12345);
Log.d(TAG, "Connected");
} catch (Exception e) {
Log.d(TAG, "Exception");
}
Log.d(TAG, "After");
}
}
}
I also tried with my own IP address while running Wireshark, and I first get [SYN] from Android to my computer and then [RST, ACK] from my computer to Android (because nothing is listening at this port), but I still do not get an exception on Android.
Also I’m testing on a physical phone (Nexus S), and I do have the internet permission in my Manifest.
Why aren't I getting an Exception?
Edit:
More precisely, the output I get is
D/TestSocket(17745): Before
D/TestSocket(17745): Connected
D/TestSocket(17745): After
(and not Exception)
In the Socket constructor, it's thrown when the IP address of the host can't be determined, so I assume that because you aren't passing a hostname which needs resolution, a different exception would be getting thrown instead. I believe the exception actually comes from the URL class or such which does the resolution, and from nowhere else.
The connect(..) method should throw an exception but doesn't appear to, as you say.
Edit: apparently Android (some versions) doesn't work properly here, so it's probably a bug: http://code.google.com/p/android/issues/detail?id=6144. It doesn't look like the link refers to the emulator as I had thought.
There are a variety of things that can cause a socket connect to fail with an exception.
However, if the SYN message that the TCP protocol sends to start the connection process is
blocked by a firewall,
routed through a borked network, or
routed to some endpoint that doesn't respond,
then TCP stack on the initiating machine will just retry, and retry. If you have a connect timeout set, you will eventually get an exception, but it could take a long time.
The fact that it works on the Android emulator and not on the real device simply means that they are implemented or configured differently. (For instance, they may have different default connect timeouts ... of the emulator may be designed to give connection refused in that scenario.)
The bottom line is that you need to make your code work on the real device. Figure out the best way to make your device set a connect timeout, and check that that works when talking to the non-existent server.
Your try catch code doesn't catch IO Exceptions. Try something like this
try
{
// to get the ip address of the server by the name<br>
InetAddress ip =InetAddress.getByName("example.com");
sock= new Socket(ip,Server.PORT);
ps= new PrintStream(sock.getOutputStream());
ps.println(" Hi from client");
DataInputStream is = new
DataInputStream(sock.getInputStream());
System.out.println(is.readLine());
}catch(SocketException e){
System.out.println("SocketException " + e);
}catch(IOException e){
System.out.println("IOException " + e);
}
The following bit of code throws java.net.SocketTimeoutException: Accept timed out:
ServerSocket serverSocket = new ServerSocket(0, 1, InetAddress.getLocalHost());
serverSocket.setSoTimeout(6000);
serverSocket.accept();
I have tried changing everything I can in creating a ServerSocket but the error remains the same. Please guide me in what I'm missing here, if anything.
What your code is doing is listening for 6 seconds for incoming TCP/IP requests on port zero for the local host1.
Here are some reasons why you might get a SocketTimeoutException.
Nothing tries to connect to your service within the 6 second timeframe.
Something tries to connect, but it is trying to connect on the wrong port. (Port zero sounds to me like you are trying to accept requests on "any" port, and I think that is unlikely to work.)
There is a software or hardware firewall (or packet filter) that is preventing connection requests from reaching your application, or is blocking the replies.
1 - If you don't want that "only accept an exception if it arrives within 6 seconds" behaviour ... which strikes me as a bit odd ... you shouldn't set a timeout on the server socket object.