I am going to create a socket and get an InputStream. Here is how I try it.
try {
final String serverIP = "111.111.111.111";
final int serverPort = Integer.parseInt(server_port);
final InetAddress serverAd=InetAddress.getByName(serverIP);
final InetAddress localAd =InetAddress.getByName(local_ip);
final int localPort = 4040;
Socket socket = new Socket(serverAd, serverPort, localAd, localPort);
}
But there is an exception thrown,
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:276)
at shootist.Porter.run(Porter.java:41)
Here the server sends me rtp data and server side is ok and confirmed. I sent invite and got 200 as well. If there is a problem in my IP and port, I think, all responses cannot delivered to my IP and given Ports. But it can't happen as the server sends me responses to my IP and given port number.
How I can fix this issue? Where I am wrong and what?
A "connection refused" error means the socket stack on the server machine received your connection request and intentionally refused to accept it. That happens for one of two possible reasons:
1) there is no listening socket running on the port you are trying to connect to.
2) there is a listening socket, but its backlog of pending connections is full, so there is no room to queue your request at that moment.
To differentiate between the two, try reconnecting a few times with a delay in between each attempt. If you get the same error consistently, then #1 is likely the culprit. Make sure the port number is correct. If #2 is the culprit, your reconnect has a chance of succeeding eventually.
Connection refused means your are try to connect to a server which is not listening on that port, or is too backlogged to accept the connection.
A simple way to test this is to try
telnet 111.111.111.111 4040
Related
I have a Java server implementation which listens for incoming TCP/IP connections on a specified port. Is there any way of finding the IP address of incoming/accepted connections?
Yes, upon accepting the incoming connection you would get a Socket instance, so you can get the address to which it is connected as follows:
String hostAddress = socket.getInetAddress().getHostAddress();
UDP in Java thinks that UDP has "connections". This surprised me, coming from a C background where I had always used UDP as a fire-and-forget type of protocol.
When testing UDP in Java, I noticed that if the remote UDP port is not listening, I get an error in Java before I attempt to send anything.
What does Java do (without me asking it to) in order to be able to tell whether a remote UDP port is listening?
(The code below is run in the receiving thread for the socket. Sending is done in a different thread.)
try {
socket = new DatagramSocket(udpPort);
socket.connect(udpAddr, udpPort);
} catch (SocketException e) {
Log.d(TAG, "disconnected", e);
}
...
while (true) {
// TODO: don't create a new datagram for each iteration
DatagramPacket packet = new DatagramPacket(new byte[BUF_SIZE], BUF_SIZE);
try {
socket.receive(packet); // line 106
} catch (IOException e) {
Log.d(TAG, "couldn't recv", e);
}
...
produces the error below, if the remote socket is not listening.
java.net.PortUnreachableException:
at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:556)
at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
at java.net.PlainDatagramSocketImpl.doRecv(PlainDatagramSocketImpl.java:161)
at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:169)
at java.net.DatagramSocket.receive(DatagramSocket.java:253)
at com.example.mypkg.MyClass.run(MyClass.java:106)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNREFUSED (Connection refused)
at libcore.io.Posix.recvfromBytes(Native Method)
at libcore.io.Posix.recvfrom(Posix.java:131)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
...
First of all, it is clear that this is not implemented using real Java. The "libcore.io" packages are not part of the Java SE libraries. These are Android stacktraces. (This doesn't change anything ... but it could.)
OK, so lets start with the exception. The javadoc for java.net.PortUnreachableException says:
"Signals that an ICMP Port Unreachable message has been received on a connected datagram."
And for DatagramSocket.connect(...):
"If the remote destination to which the socket is connected does not exist, or is otherwise unreachable, and if an ICMP destination unreachable packet has been received for that address, then a subsequent call to send or receive may throw a PortUnreachableException. Note, there is no guarantee that the exception will be thrown."
So here's what I think has happened. Prior to creating the incoming socket, something on the client system has sent a UDP packet to the server on that port, and the server has responded with an ICMP Port Unreachable. Then your socket is created, and connected, and you call receive. This does a recvfrom syscall, and network stack responds with an ECONREFUSED error code ... which Java turns into a PortUnreachableException,
So does this mean that UDP is connection oriented?
Not really, IMO. It is simply reporting the that it received an ICMP message in response to something that happened earlier.
What about the connect methods, and the "connected socket" / "connected datagram" phraseology?
IMO, this is just some clumsy wording. The "connection" is really just referring to the fact that the datagram socket has been bound to a specific remote address and port ... so that you can send and receive datagrams without specifying the IP and port1.
These "connections" are pretty tenuous and certainly don't amount to making UDP "connection oriented".
What does Java do (without me asking it to) in order to be able to tell whether a remote UDP port is listening?
It is not doing anything. Java is simply reporting information from a previous ICMP message.
1 - Actually, there is a bit more to it than that. For example, binding tells the client-side OS to buffer UDP packets from that host / port an route UDP packets (and ICMP notifications) to the application. It also tells it not to respond with an ICMP Port Unreachable.
UDP in Java thinks that UDP has "connections".
No it doesn't, but UDP (regardless of Java) does have connected sockets. Not the same thing.
This surprised me, coming from a C background where I had always used UDP as a fire-and-forget type of protocol.
You can connect() a UDP socket in C too. Look it up. What you describe has nothing to do with Java specifically.
When testing UDP in Java, I noticed that if the remote UDP port is not listening, I get an error in Java before I attempt to send anything.
That's because you connected the socket. One of the side-effects of that is that incoming ICMP messages can be routed back to the sending socket in the form of errors.
What does Java do (without me asking it to) in order to be able to tell whether a remote UDP port is listening?
It calls the BSD Sockets connect() method.
The UDP server needs to listen on a local port.
Here's a code stub for a server.
int portNumber = 59123;
DatagramSocket server = new DatagramSocket(portNumber);
// read incoming packets
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while(true)
{
server.receive(packet);
byte[] data = packet.getData();
String text = new String(data, 0, packet.getLength());
echo(packet.getAddress().getHostAddress() + ":" + packet.getPort() + " received: '" + text + "'");
}
I am new and I've a question.
In android, I can't connect any remote address via TCP Socket. When I tried to connect, debugger shows an error:
Exception: failed to connect to /23.20.47.114 (port 9339) after 2000ms: connect failed: EINVAL (Invalid argument), OSVersion: 4.1.1(Jellybean)
And the code:
void run(){
Socket s=new Socket();
s.bind(getAddress("192.168.0.45",8080)); <-It's bound successfully.
s.connect(getAddress("23.20.47.114",9339)); <-Error
writeData(s);
}
InetSocketAddress getAddress(String host, int port){[code]}
void writeData(Socket so){[code]}
Note: This server is always open and sorry for my english.
You already bound the socket to a local IP address using bind(), so it does not make sense to also connect the same socket to a remote server. Try getting rid of the bind() statement.
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.
I am getting below error when I am trying to connect to a TCP server. My programs tries to open around 300-400 connections using diffferent threads and this is happening during 250th thread. Each thread uses its own connection to send and receive data.
java.net.SocketException: Connection timed out:could be due to invalid address
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:372)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:233)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:220)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:385)
Here is the code I have that a thread uses to get socket:
socket = new Socket(my_hostName, my_port);
Is there any default limit on number of connections that a TCP server can have at one time? If not how to solve this type of problems?
You could be getting a connection timeout if the server has a ServerSocket bound to the port you are connecting to, but is not accepting the connection.
If it always happens with the 250th connection, maybe the server is set up to only accept 250 connections. Someone has to disconnect so you can connect. Or you can increase the timeout; instead of creating the socket like that, create the socket with the empty constructor and then use the connect() method:
Socket s = new Socket();
s.connect(new InetSocketAddress(my_hostName, my_port), 90000);
Default connection timeout is 30 seconds; the code above waits 90 seconds to connect, then throws the exception if the connection cannot be established.
You could also set a lower connection timeout and do something else when you catch that exception...
Why all the connections? Is this a test program? In which case be aware that opening large numbers of connections from a single client stresses the client in ways that aren't exercised by real systems with large numbers of different client hosts, so test results from that kind of client aren't all that valid. You could be running out of client ports, or some other client resource.
If it isn't a test program, same question. Why all the connections? You'd be better off running a connection pool and reusing a much smaller number of connections serially. The network only has so much bandwidth after all; dividing it by 400 isn't very useful.