Socket programming - Client (linux), server (Windows) - java

I'm trying to create simple socket application using sockets to send stream from linux (64x ArchLinux) to server (Windows XP).
Code I'm using I found on the internet, just to check if it is working. What is interesting the code works perfectly if I'm using Windows XP (server) and Win 8 (client), but when client is on ArchLinux it does not work. Is there some special way to connect Windows-Linux ?
Server.java
import java.lang.*;
import java.io.*;
import java.net.*;
class Server_pzm {
public static void main(String args[]) {
String data = "Toobie ornaught toobie";
try {
ServerSocket srvr = new ServerSocket(1234);
Socket skt = srvr.accept();
System.out.print("Server has connected!\n");
PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
System.out.print("Sending string: '" + data + "'\n");
out.print(data);
out.close();
skt.close();
srvr.close();
}
catch(Exception e) {
System.out.print("Whoops! It didn't work!\n");
}
}
}
Client.java
import java.lang.*;
import java.io.*;
import java.net.*;
class Client {
public static void main(String args[]) {
try {
Socket skt = new Socket("192.168.224.78", 1234);
BufferedReader in = new BufferedReader(new
InputStreamReader(skt.getInputStream()));
System.out.print("Received string: '");
// while (!in.ready()) {} line removed
System.out.println(in.readLine());
System.out.print("'\n");
in.close();
}
/* lines removed catch(Exception e) {
System.out.print("Whoops! It didn't work!\n");
} */
// added exception handling
catch(UnknownHostException e) {
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
}
}
EDIT
Sorry, I did not specify what I meant by not working. I meant I got an exception which later prints System.out.print("Whoops! It didn't work!\n"); as in the catch blok. Win 8 and Arch Linux are installed on the same laptop, while the code is on my dropbox folder in both systems (so the code is the same) - I will post the actual exception, after I get back to my laptop
EDIT 2:
I updated code and this is exception I got:
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)

java.net.ConnectException: Connection refused
This has two possible meanings.
There is nothing listening at the address:port you tried to connect to.
There is a firewall rule in the way.
More likely 1. Firewalls usually just drop the packets, which causes a connection timeout rather than a refusal.

Are you sure you can establish connection between those systems? I have compiled and run your code on Windows 7 and Linux Mint on Virtualbox and it works correctly.
What do you mean "It doesn't work"? Does it throw any exception? If you just don't have any output, try to run it again and wait about 30 seconds.
For me it's just a network problem. So you should also try to ping your windows machine from linux and then try to telnet to server.
Edit:
So we know it is a network problem. First try to ping ip server from Linux system.
ping 192.168.224.78
If it didn't work, you should check if both machines are in the same subnet 192.168.224.0 assuming the mask is 255.255.255.0. You need just to type ifconfig in console.
In next step you should try to disable windows firewall. Here is an instruction how to do that.

Related

Java Sockets Can't Access Server using Subnet IP Address

Using JDK 10, am trying to write a client / server program that will run separately on multiple computers using TCP/IP sockets.
All computers should be in same local subnet 192.168.1.x (where x can be varied between 1 and 254).
The individual servers receive a string from the client program and print out the string.
ServerThread.java:
import java.io.IOException;
import java.net.ServerSocket;
import java.util.concurrent.Executors;
public class ServerThread implements Runnable {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
System.out.println("Connected" + socket);
try {
var in = new Scanner(socket.getInputStream());
var out = new PrintWriter(socket.getOutputStream(), true);
while (in.hasNextLine()) {
out.println(in.nextLine());
}
}
catch (Exception e) {
System.out.println("Error:" + socket);
}
finally {
try {
socket.close();
}
catch (IOException e) {
}
System.out.println("Closed: " + socket);
}
}
public static void main(String[] args) throws IOException {
try (var listener = new ServerSocket(6500)) {
System.out.println("Server has started...");
var pool = Executors.newFixedThreadPool(20);
while (true) {
pool.execute(new ServerThread(listener.accept()));
}
}
}
}
Originally, it would work with "localhost" as the hostName:
public class Client {
public static void connect(String hostName, String portNumber) throws Exception {
int port = Integer.parseInt(portNumber);
try (var socket = new Socket(hostName, port)) {
System.out.println("Enter lines of text then Ctrl+D or Ctrl+C to quit");
var scanner = new Scanner(System.in);
var in = new Scanner(socket.getInputStream());
var out = new PrintWriter(socket.getOutputStream(), true);
while (scanner.hasNextLine()) {
out.println(scanner.nextLine());
System.out.println(in.nextLine());
}
}
}
public static void main(String[] args) throws Exception {
Client.connect("localhost", "6500");
}
}
Now when using new Socket(InetAddress.getByName(ipAddress), port), I get java.net.ConnectException: Connection refused Exception:
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void connect(String iPAddress, String portNumber) throws Exception {
int port = Integer.parseInt(portNumber);
try (var socket = new Socket(InetAddress.getByName(iPAddress), port)) {
System.out.println("Enter lines of text then Ctrl+D or Ctrl+C to quit");
var scanner = new Scanner(System.in);
var in = new Scanner(socket.getInputStream());
var out = new PrintWriter(socket.getOutputStream(), true);
while (scanner.hasNextLine()) {
out.println(scanner.nextLine());
System.out.println(in.nextLine());
}
}
}
public static void main(String[] args) throws Exception {
Client.connect("192.168.1.1", "6500");
}
}
Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402)
at java.base/java.net.Socket.connect(Socket.java:591)
at java.base/java.net.Socket.connect(Socket.java:540)
at java.base/java.net.Socket.<init>(Socket.java:436)
at java.base/java.net.Socket.<init>(Socket.java:246)
at com.sample.Client.connect(Client.java:13)
at com.sample.Client.main(Client.java:26)
However, when I try using "192.168.1.2", nothing happens (it doesn't even print out: Enter lines of text then Ctrl+D or Ctrl+C to quit)
And eventually, it times out by throwing this Exception:
Exception in thread "main" java.net.ConnectException: Operation timed out (Connection timed out)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402)
at java.base/java.net.Socket.connect(Socket.java:591)
at java.base/java.net.Socket.connect(Socket.java:540)
at java.base/java.net.Socket.<init>(Socket.java:436)
at java.base/java.net.Socket.<init>(Socket.java:246)
at com.sample.Client.connect(Client.java:13)
at com.sample.Client.main(Client.java:26)
Questions:
Why is it throwing this exception: java.net.ConnectException: Connection refused when using 192.168.1.1 and java.net.ConnectException: Operation timed out (Connection timed out) when using any digit other than 1 for the host (last digit), e.g. 192.168.1.2 ?
Is there some other Java 10 API (e.g. reactive streams or NIO channels) that is better than just using Threads for the Server?
I think you should also be aware of some system tools to debug at a black box level about your application in order to figure out possible issues:
I am a Linux person, so know only about Linux utilities:
"sudo netstat -tpln" to find out if your server application is listening on the desired port, and most importantly it should be listening on the IP 0.0.0.0 and not just 127.0.0.1 in order for network computers to be able to connect to it.
"sudo iptables -vnL" to find out if the firewall is not blocking external originated connections to your server applications. If this is the case, then client app on the same system where your server app resides will be able to communicate, but not the same client app on other systems on the same network.
In my experience these debugging helps resolve such issues in more than 90% of time and it is usually not a programming issue. I hope this info helps.
Figured it out - my router / firewall assigns different computers inside my network to different Subnet based IP addresses but doesn't necessarily will assign the second computer (subsequentially) to:
191.168.1.2
Ran an ifconfig and discovered the particular Subnet based IP address which was 192.168.1.x the real value of "x" was omitted for security reasons.
The mistake is to assume that Socket constructor uses both IP and hostname, in reality:
new Socket("192.168.1.2", 6500)
doesn't work because it expects hostname. From this doc:
host - the host name, or null for the loopback address.
. . .
public Socket(String host,int port) throws UnknownHostException, IOException
What you have to use is:
new Socket(InetAddress.getByName("192.168.1.2"), 6500)

Java Socket connect gives success when connecting to an unknown IP address... why?

I would like to connect by TCP to a machine given its IP address and its port.
I decided to use the JAVA java.net.Socket class and its connect method as it seems to fit my need.
For testing purpose, as the machines I need to test are not yet available, I tried to connect a local machine on its standard port 80.
But I was very surprised to see that it succeeded with any IP address, even an unknown one: I cannot "ping" it, but the connect method gives me success...
Did I missed something in JAVA Socket understanding?
How is this behaviour possible?
Here is my code :
private void testSocketConnection() {
try (Socket socketToMachine = new Socket()) {
InetSocketAddress address = new InetSocketAddress(InetAddress.getByName("1.2.3.4"), 80);
socketToMachine.connect(address, 1000);
System.out.println("SUCCESS");
} catch (UnknownHostException uhe) {
System.out.println("UnknownHostException");
} catch (IOException ioe) {
System.out.println("IOException");
}
}

How to verify the ACE-CORBA service local windows machine

I'm able to create docker container for ACE-TAO service , and able to access it from parent windows machine using port-forwarding concept.
From browser i try to hit the localhost:forward-port and getting "ERR_EMPTY_RESPONSE" and TAO service is running in docker container.
If I want to verify in local, whether its connected properly or not.
How can I write Java code to verify?
The following java code connects to localhost:17500 and prints out a message saying whether or not it could create a tcp connection.
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String argv[]) throws Exception
{
try {
Socket clientSocket = new Socket("localhost", 17500);
System.out.println("Could connect");
}
catch (ConnectException e) {
System.out.println("Cannot connect");
}
}
}

Client-Server connects while being on the same computer but not while being run on different ones

I'm trying to build a basic client-server application.
When I run both the server and the client on the same computer both manage to connect without a hitch but if I try to do so from different computers (desktop and laptop) the connection doesn't get though. The server isn't even aware that someone tried to connect to it while the client timeouts after a while. At first I assumed that it's a firewall problem but disabling the firewall completely on the server PC did not help. Tried changing ports and checked on multiple computers. Any ideas what could cause this?
I control both the server and the client and can change the code of both if necessary. The server always runs on the same PC and I'm connecting to it directly using hardcoded IP address.
This is the code of the client sending random int to the server.
public static void main(String[] args) {
Socket s = new Socket();
try {
s.connect(new InetSocketAddress("123.45.67.891", 8084), 5000);
s.getOutputStream().write(42);
s.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
The server is slightly more complicated but considering the fact that they manage to connect while being run from the same PC I assume that the problem isn't with it.
edit: Server code (Thread per client. There shouldn't be too many of those)
public void run() {
try {
serverSocket = new ServerSocket(listenPort); //integer
} catch (IOException e) { ... }
while (shouldRun) {
try {
Socket clientSocket = serverSocket.accept(); // Blocked here while trying to connect from remote computer
//Never gets here
ConnectionHandler newConnection = connectionHandlerCreator.create(clientSocket);
connectionHandlers.add(newConnection);
newConnection.initialize();
new Thread(newConnection).start();
} catch (IOException e) { ... }
}
}
Initialize consists of the following (which latter used for I/O).
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
The problem is probably on your server side though: you have to make it respond to all ip's not just local one, by using the constructor:
ServerSocket(int port)
it will default accepting connections on any addresses which is not the case if you specified an IP

Java detect disconnect from Server in Client

I made an java-application which has a client- and a server-side. Both sides communicate via sockets. This works well until my server application is killed by something and can't close or shutdown the serversocket.
The client does not seem to notice the broken connection and just hangs itself while trying to read the next object.
I also tried sending a test object from the client every 5 seconds to detect that the server is offline, but that also does not work.
I might have to mention this only occurs when running the server app on Windows and the client on Linux (Ubuntu in VirtualBox). Windows-Windows works fine. Netstat even gives me an ESTABLISHED on Linux, although I already killed the server.
Client code:
requestSocket = new Socket("192.168.1.3", 1234);
out = new ObjectOutputStream(new CipherOutputStream(requestSocket.getOutputStream(), ec));
in = new ObjectInputStream(new CipherInputStream(requestSocket.getInputStream(), dc));
new Thread() {
public void run() {
while(true) {
try {
out.writeObject(obj);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("sent");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
}
}
}.start();
Server code:
serverSocket = new ServerSocket(1234);
socket = serverSocket.accept();
out = new ObjectOutputStream(new CipherOutputStream(clientSocket.getOutputStream(), ec));
in = new ObjectInputStream(new CipherInputStream(clientSocket.getInputStream(), dc));
//do-while-reading on the socket[...]
I read multiple threads which told me how to detect a lost connection on the server side, but found none for the client side or the answers did not work for me.
Set a read timeout on the socket, of suitable duration, enough to include all normal transfers, and catch SocketTimeoutException.
The problem seemed to be the VM. When testing it on my Laptop with Manjaro Linux, everything worked as it should have in the beginning!
Thank you for your contributions anyway. :)

Categories