I'm trying to create a new socket, but it keeps finding a IO Exception, saying
Couldn't get the I/O for the connection to: localhost.
Here is my code snippet:
Socket mySocket = null;
BufferedReader in = null;
try{
mySocket = new Socket("localhost",4444);
in = new BufferedReader( new InputStreamReader(mySocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: localhost.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get the I/O for " + "the connection to: localhost.");
System.exit(1);
}
I tried to change my hostname "localhost" to also my hostname for my computer (i.e. typing in hostname in cmd to find hostname). Also tried another port, but it all keeps giving me the same error. What are some tips or ways to debug this? Or can you pinpoint what the problem is? Thank you for your help.
It means that no-one is listening to the port 4444 on your machine. Socket is the connector to channel that have 2 edges: sockets. Typically there is one ServerSocket on server side and Socket on client side.
Related
I have written a code in java to interface my computer with a transmitter a transmitter device, with a communication board already implemented and ready to connect via TCP/IP to any server with a specific address IP (say 192.168.2.2) and listening to a specific port number (say 4000).
I followed the exact strep how to create a server side application in Java offering a that listening port, so that I can connect to that transmitter.
I don't understand why when I try to debug the code, it blocks a the line clientSocket = serverSocket.accept(), and throws a timeout exception.
Could someone help me find out where the error might be in my code?
Any help would be greatly appreciated.
Thanks.
Here is the code:
public class Server {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Declares server and client socket, as well as the input and the output stream
ServerSocket serverSocket = null;
Socket clientSocket = null;
PrintWriter out;
//BufferedReader in;
BufferedReader in;
try{
InetAddress addr = InetAddress.getByName("192.168.2.2");
//Opens a server socket on port 4000
serverSocket = new ServerSocket(4000) ;
//Sets the timeout
serverSocket.setSoTimeout(30000);
System.out.println("Server has connected");
//Create a connection to server
System.out.println("Server listening connection from client ....");
//Listens and waits for client's connection to the server
clientSocket = serverSocket.accept();
// Creates input and output streams to socket
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//Reads response from socket
while((in.readLine())!= null ){
System.out.println ( in.readLine() );
}
System.out.println ( "Closing connection ....");
//Terminates connection
clientSocket.close();
serverSocket.close();
System.out.println("Connecton successfully closed");
}
catch(IOException e){
System.out.println(e);
}
}
}
Could someone help me find out where the error might be in my code?
There is no error in your code that could cause this problem. Clearly you haven't configured the device to connect to this server correctly, or the device isn't running, or it isn't connecting, or there is a firewall in the way. Investigate that.
However:
InetAddress addr = InetAddress.getByName("192.168.2.2");
What is this for? It isn't used.
System.out.println("Server has connected");
This is simply not true. The server hasn't connected. At this point all it has done is create a listening socket.
while((in.readLine())!= null ){
Here you are reading a line and throwing it away.
System.out.println ( in.readLine() );
Here you are printing every second line, having thrown every odd line away. The correct way to write this loop is:
String line;
while ((line = in.readLine()) != null)
{
System.out.println(line);
}
Note also that this server will service exactly one client and then exit. There should be a loop around everything from accept() to clientSocket.close(), and if there are multiple devices it should start a new thread per accepted socket to handle the I/O.
You specified timeout of 30 seconds, didn't you? :
serverSocket.setSoTimeout(30000);
So after 30 seconds, no matter whether stopped in debugger or running, this will timeout and throw exception.
I have TCP server-client application. It works but sometime something happens. Client connects to server but server says he doesn't accepted him.
Server side code:
while(!stopped){
try {
AcceptClient();
} catch(SocketTimeoutException ex){
continue;
} catch (IOException ex) {
System.err.println("AppServer: Client cannot be accepted.\n"+ex.getMessage()+"\n");
break;
}
...
private void AcceptClient() throws IOException {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(200);
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("Accepted connection from "+clientSocket.getInetAddress());
}
Client side code:
try {
socket = new Socket(IPAddress, serverPort);
socket.setSoTimeout(5000);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e1) {
sendSystemMessage("DISCONNECTED");
sendSystemMessage(e1.getMessage());
return;
}
sendSystemMessage("CONNECTED");
If client connects the message:
Accepted connection from ... appears. But sometimes it doesn't appear
even if client sends message "CONNECTED"
Server is still runing the loop trying to get client and it is catching socketTimeoutException. Client is connected, sends message and waits for response.
I suspect a missing 'flush' inside your client's 'sendSystemMessage()'.
Unfortunately the constructor of ObjectInputStream attempts to read a header from the underlying stream (which is not very intuitive IMHO). So if the client fails to flush the data - the server may remain stuck on the line "in = new ObjectInputStream(socket.getInputStream())"...
As a side note it's usually better for a server to launch a thread per incoming client, but that's just a side remark (plus it obviously depends on requirements).
I found the problem. The communication on my net is too slow so it timeouts in getting inputstream. The solution has two parts. Flushing outputstream before getting inputstream. And set socket timout after streams are initialized.
serverside:
clientSocket = serverSocket.accept();
out = new ObjectOutputStream(clientSocket.getOutputStream());
out.flush()
in = new ObjectInputStream(clientSocket.getInputStream());
clientSocket.setSoTimeout(200);
I'm trying to create a socket that connects to a server. A user can manually enter the socket's IP address and IP port.
When the address and port are valid nothing goes wrong, but when they don't, it causes my entire app to freeze.
This is the code:
public void connect() {
try {
String txHostIP = settings.getString("txHostIP", "");
int txHostport = Integer.parseInt(settings.getString("txHostPort", ""));
//Where it all goes wrong. The program just hangs here for eternity
socket = new Socket(txHostIP, txHostport);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
showMessage(context, "Something went wrong");
}
}
What I want is for a message to pop up when no connection can be made but the program doesn't throw an exception if an IP port or address is incorrect.
How can I fix this? Any help is greatly appreciated!
EDIT:
I've added some System.out prints to show how the program hangs. I've also added a socket connect timeout of 5 seconds. Still the program won't even reach that block of code.
public void connect() {
try {
String txHostIP = settings.getString("txHostIP", "");
int txHostport = Integer.parseInt(settings.getString("txHostPort", ""));
System.out.println("1");
socket = new Socket(txHostIP, txHostport);
System.out.println("2");
socket.connect(socket.getLocalSocketAddress(), 5000);
System.out.println("3");
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("4");
} catch (IOException e) {
showMessage(context, "Something went wrong");
}
}
It just prints the 1 and then hangs on forever.
If you want to let the socket abort after a certain amount of time you have to do this:
int timeout = 5000;
int port = 1234;
String address = "localhost";
InetSocketAddress inetAddress = new InetSocketAddress(address, port);
Socket socket = new Socket();
socket.connect(inetAddress, timeout);
Otherways the socket will hang before you set the soTimeout. The connect method will throw an SocketTimeoutException if the remote host is not reachable.
Set a connection timeout of say, 5 seconds - run a counter based on the system clock and when the time is up, if it hasn't connected - throw the exception and cancel the connection.
The below program causes this issue
EDITED:
import java.io.*;
import java.net.*;
public class smtpClient {
public static void main(String[] args) {
// declaration section:
// smtpClient: our client socket
// os: output stream
// is: input stream
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
// Initialization section:
// Try to open a socket on port 25 : step 1
// Try to open input and output streams: step 2
try {
smtpSocket = new Socket("192.168.1.2", 1024);
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: hostname");
}
// If everything has been initialized then we want to write some data
// to the socket we have opened a connection to on port 25
if (smtpSocket != null && os != null && is != null) {
try {
// The capital string before each colon has a special meaning to SMTP
// you may want to read the SMTP specification, RFC1822/3
os.writeBytes("HELO\n");
os.writeBytes("MAIL From: k3is#fundy.csd.unbsj.ca\n");
os.writeBytes("RCPT To: k3is#fundy.csd.unbsj.ca\n");
os.writeBytes("DATA\n");
os.writeBytes("From: k3is#fundy.csd.unbsj.ca\n");
os.writeBytes("Subject: testing\n");
os.writeBytes("Hi there\n"); // message body
os.writeBytes("\n.\n");
os.writeBytes("QUIT");
// keep on reading from/to the socket till we receive the "Ok" from SMTP,
// once we received that then we want to break.
String responseLine;
while ((responseLine = is.readLine()) != null) {
System.out.println("Server: " + responseLine);
if (responseLine.indexOf("Ok") != -1) {
break;
}
}
// clean up:
// close the output stream
// close the input stream
// close the socket
os.close();
is.close();
smtpSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
}
Console Log :
Couldn't get I/O for the connection to: hostname
The program I took is from :
http://www.javaworld.com/jw-12-1996/jw-12-sockets.html?page=4
I have already tried modifying the port from 25 to 1024
I am running it on my local PC, so I am admin on this system, but not sure if there is any default firewall issue(running this in eclipse on windows 7)
As per your comments below : DO I need to make a listner, which mean to say a Server Socket, which will listen to smtp client requests
Answer is: according to details what you have provided, there is no listener running or machine with specified IP and port number.
UPD: then you are trying to connect to somewhere you do have to be sure that there is something which listens on other side, either writing your own server code or by using a 3rd party server/code to provide certain service on a port number you are trying to reach.
Why would you expect that there is a mail server running on machine with an address you've provided?
It sounds like some other program is using port 1024.
Try a different port.
I am writing a port scanner in Java and I want to be able to distinct the following 4 use cases:
port is open
port is open and server banner was read
port is closed
server is not live
I have the following code:
InetAddress address = InetAddress.getByName("google.com");
int[] ports = new int[]{21, 22, 23, 80, 443};
for (int i = 0; i < ports.length; i++) {
int port = ports[i];
Socket socket = null;
try {
socket = new Socket(address, port);
socket.setSoTimeout(500);
System.out.println("port " + port + " open");
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String line = reader.readLine();
if (line != null) {
System.out.println(line);
}
socket.close();
} catch (SocketTimeoutException ex) {
// port was open but nothing was read from input stream
ex.printStackTrace();
} catch (ConnectException ex) {
// port is closed
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The problem is that I get a ConnectionException both when the port is closed and the server cannot be reached but with a different exception message:
java.net.ConnectException: Connection timed out: connect
when the connection was never established and
java.net.ConnectException: Connection refused: connect
when the port was closed
so I cannot make the distinction between the two use cases without digging into the actual exception message.
Same thing happens when I try a different approach for the socket creation. If I use:
socket = new Socket();
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(address, port), 1000);
I have the same problem but with the SocketTimeoutException instead. I get a
java.net.SocketTimeoutException: Read timed out
if port was open but there was no banner to be read and
java.net.SocketTimeoutException: connect timed out
if server is not live or port is closed.
Any ideas? Thanks in advance!
I don't think you have any options besides parsing the exception message. Is there a reason you'd rather not do this?
ConnectException only has an empty constructor and an errorMesssage constructor. There are no subclasses of ConnectException in the API. So I am afraid, Java does no proper way to access the reason. Parsing the exception message seems to be the only way, despite it being really messy with translations.