I was trying to implement a simple server program in python and client program in java.
Python server runs well. And Java client compiles good. But cannot connect to Python server.
This is my server.py
import sys
import socket
HOST = ""
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created")
try:
s.bind((HOST, PORT))
except Socket.error as msg:
print("Bind failed.")
print("Error code: "+str(msg[0]))
print("Message: "+str(msg[1]))
sys.exit()
print("Socket bind complete")
s.listen(10)
print("Socket now listening")
while 1:
conn, addr = s.accept()
print("Connected with: "+addr[0])
print(str(addr[1]))
s.close()
And this is my Client.java file:
import java.net.Socket;
import java.io.IOException;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
System.out.println("Connected");
socket.close();
System.out.println("Socket closed");
} catch(IOException exception) {
exception.printStackTrace();
}
}
}
Python server listens to Port 8888. But Java client cannot connect.
This is the output when I run Client:
java Client
And the output:
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at Client.connect(Client.java:84)
at Client.<init>(Client.java:65)
at Client.main(Client.java:301)
Error connecting to localhost at 5555
Why can't it connect? When I write an equivalent Java server program, it works fine.
This is my Java server: Server.java
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.IOException;
public class ChatServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InetAddress ip = socket.getInetAddress();
System.out.println("Client connected: "+ip.getHostAddress());
socket.close();
} catch(IOException exception) {
exception.printStackTrace();
}
}
}
So my question is short:
Why is Client.java connected to Server.java but not Server.py?
Any help would be appreciated. Thankyou.
Seems like you never cleanly close the socket in your Python code, so it could still be stuck from a previous run attempt? Also, your python program currently doesn't do anything with the connection once received, just keeps trying to accept.
Try something like this:
while(1):
conn, addr = s.accept()
print("Connected with: "+addr[0])
#Waits for any incoming data and echoes it back
while(1):
data = conn.recv(1024)
#break if not found to get to close statement which was never reached in old code
if not data: break
print("Received data:", data.decode())
conn.sendall(data)
conn.close()
I use the exact Python code and Java code you post, it seems work fine, may be something wrong with your environment? you can diagnosis the problem with following steps(assume you run your program in a linux box like me):
1.just run the python server script
./server.py
2.use netcat to see if the server is good for connect
nc -zv localhost 8888
if things goes well, you may see connect established as expected.
if not working, use netcat to build a tcp server listen on port 8888
nc -l -p 8888
and connect to it with your java program.
you can also use netstat to distinguish if server.py works fine
sudo netstat -ntlp | grep :8888
I think I can solve your problem, but I do not know why.
You can have a try by adding an item on firewall config with
-A INPUT -i lo -j ACCEPT
then, restart your iptables service.
Related
I have 2 java programs, Server and Client.
I am trying to connect the client program to the server program using java socket programming.
Here is the Server program :
public class ServerX {
public static void main(String[] args) {
ServerSocket ss = new ServerSocket(987);
Socket s = ss.accept();
InetSocketAddress isa1 = (InetSocketAddress) s.getRemoteSocketAddress();
System.out.println(isa1.getPort());
ss.close();
}
}
And here is the Client program :
public class ClientX {
public static void main(String[] args) {
Socket s = new Socket("ip of the server", 987);
s.close();
}
}
I expected that isa1.getPort() in the Server program gives 987, but it actually gives 52532 instead.
So what is the problem, and what 53532 means?
TCP is a full duplex communication protocol it means both side of an established connection allowed to send and received data.
so server is listening on port 987 but client side also need a port on it's own side to receive data that is being sent from server side and about the connection in case of ClientX, server will listen to incoming requests on port number 987 but if want sent something as reply to ClientX will write on port 53532 of the connection
Not sure on requirement over here. But if you wish to perform a sanity check on Static port and usage of Java is not a pre-cursor, then I feel below script must help you. I had referred to Python Docs (https://docs.python.org/2.6/library/socket.html) for getting help in past for one of my project requirement.
''' Simple socket server using threads
'''
import socket
import sys
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 61901 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
s.close()
Herein PORT = 61901 can be replaced with required port.
Right now, I made a simple server in java as so:
import Java.net.*;
import Java.io.*;
import Java.util.*;
class Server{
public static void main(String[] args){
int PORT = 13;
try(ServerSocket server = new ServerSocket(PORT)){
while(true){
try(Socket connection = server.accept()){
Writer out = new OutputStreamWriter(connection.getOutputStream());
Date now = new Date();
out.write(now.toString());
out.flush();
connection.close();
} catch(IOException ex){}
}
}
catch(IOException ex){
System.err.println(ex);
}
}
}
I compile and run this from the command line. Being on Port 13, I try to run this on telnet as so: telnet localhost 13 but all it gives me is "Connection to host lost". Mind you, I did this after enabling telnet on Windows 10 and installing it. Is there a simple step I'm missing?
Telnet won't connect to localhost ...
Yes it did. That's why it said 'connection to host lost' instead of 'connection refused'.
And here's what happened. You coded:
connection.close();
You got:
connection to host lost
You closed the connection; Telnet told you so.
That's what's supposed to happen.
There is no problem here to solve.
Or else you got an I/O exception in the server accept loop.
But as you are ignoring them it is impossible to say which.
In your program, following events occurs:
Server starts at 13
telnet localhost 13 : connects to that server
As soon as connection is established, server sends date
You will see date on your client
out.flush() says the client I am done writing
telnet client don't understand server command (Date)
telnet closes the connection
Telnet - Connection to host lost - on port 1099 in local machine
I've asked this question yesterday and no one was able to figure out the problem I was having. So I was hoping of providing a more up to date code with the suggestions from yesterday added on. Basically, I've been trying to form a connection between a server and a client but whenever I executed the server then the client, I'd get this exception: Address already in use. The obvious answer would be to give it a new port, but even then I still get this error. I'm assuming it has something to do with my code somewhere going wrong. Can anyone spot it please? I have attached the server class and the client class.
This is the error I get:
Exception in thread "main" java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
at java.net.ServerSocket.bind(ServerSocket.java:376)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at MessageServer.main(MessageServer.java:16)
Server code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class MessageServer {
public static void main(String[] args) throws IOException {
try {
int port = 53705;
ServerSocket server = new ServerSocket(port);
while (true) {
System.out.println("Waiting for client...");
//server.setReuseAddress(true);
Socket client = server.accept();
System.out.println("Client from " + server.getInetAddress() + " connected.");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine = in.readLine();
System.out.println("Client said: '"+inputLine+"'");
Writer count = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
byte c [] = count.toString().getBytes();
count.flush();
count.close();
in.close();
}
} catch (IOException e) {
System.err.println(e);
}
}
}
Client code:
import java.net.*;
import java.io.*;
public class MessageSendClient {
public static void man(String args[]) throws IOException {
String servername = "localhost";
int port = 53705;
Socket server;
//server.setReuseAddress(true);
try {
server = new Socket (servername,port);
System.out.println("Connected to " + server.getInetAddress());
DataInputStream in = new DataInputStream(new BufferedInputStream(server.getInputStream()));
server.close();
byte c[] = new byte[100];
int num = in.read(c);
String count = new String(c);
System.out.println("Server said: " + count);
} catch (Exception e) { }
}
}
You're getting the error when the server program attempts to open up a socket on port 53705 for listening. The Address already in use message means just that, another process on your machine is already using port 53705. It could be that some daemon process has opened this same port by coincidence, or your web browser has opened this port and is still using it.
Most likely, though, is that you have another instance of your server program running somewhere in the background. Check all your terminal windows, or check your IDE for tabs containing the status of running programs.
By the way, "unique port" is a bit misleading, as port 53705 isn't "unique" in any way, it just happens to be a port number you (or somebody) picked that you hope isn't already in use. To get a truly unique port, use new ServerSocket(0) which will ask the system to allocate an unused port. To find out which port was assigned, use serverSocket.getLocalPort(). You might print it out, and then pass it to the client program as a command-line option.
I think you are running into a plattform and java liberary specific issue.
Please provide additional infos about your os plattform (x86/x64) and which version of jdk from which vendor are you using?
According to this Link
http://www.oracle.com/technetwork/java/javase/7u51-relnotes-2085002.html
Above Oracle JDK 7u51: The default socket permissions assigned to all code including untrusted code have been changed. You can only bind sockets to the ephemeral port range on each system.
Port 53705 should be a save ephemeral port.
But still use
netstat -an | grep 53705
to double check if the port is used in linux and use netstat or tcpview for windows.
You can use
less /proc/sys/net/ipv4/ip_local_port_range
for linux to check your ephemeral port range for linux and find
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
in windows to get determine your ephemeral port range. More about ephemeral range in windows can be found in how to change/view ephemeral port range in windows machines
I can confirm your server code and client without the "man" -> "main" typo is running under Opensuse 12.3 with
Java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (suse-8.32.5-i386)
OpenJDK Client VM (build 24.45-b08, mixed mode)
jvm is running by an non admin user with groups: www,dialout,video,shadow,users
I tested your code and it works correctly (meaning: I can connect to the server, didn't test the rest). Just pay attention to the main method in MessageSendClient, there's a typo ("man" instead of "main") and the correct signature is:
public static void main(String[] args)
not
public static void main(String args[]) // Still compatible but not recommended (C-like syntax)
Make sure the listening port is free by executing (replace YOUR_PORT with the number)
netstat -tulpn | grep :YOUR_PORT
because that's the reason why you get that exception. If you're on Windows you might just run
netstat -an
and search for the port.
I am trying to connect server by port and Host Name.
I find one program but when i am trying to run it will show following Exception
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:69)
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.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
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)
at sample.Echoclient2.main(Echoclient2.java:31)
Couldn't get I/O for the connection to: 127.0.0.1
Java Result: 1
Here is my code which i use.
public class Echoclient2 {
public static void main(String[] args) throws IOException {
String serverHostname = new String ("127.0.0.1");
if (args.length > 0)
serverHostname = args[0];
System.out.println ("Attemping to connect to host " +
serverHostname + " on port 10008.");
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket(serverHostname, 10008);
System.out.println("server name"+Inet4Address.getByName(serverHostname));
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
System.out.println("Connection accepted " +
echoSocket.getInetAddress() + ":" +
echoSocket.getPort());
} catch (UnknownHostException e) {
e.printStackTrace();
System.err.println("Don't know about host: " + serverHostname);
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Couldn't get I/O for "
+ "the connection to: " + serverHostname);
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
System.out.println ("Type Message (\"Bye.\" to quit)");
while ((userInput = stdIn.readLine()) != null)
{
out.println(userInput);
// end loop
if (userInput.equals("Bye."))
break;
System.out.println("echo: " + in.readLine());
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
What i need:
1. I need to send some message to server and want response from server. Suppose i send "I am user of stackoverflow" then server should give any response like return same String or convert in uppercase or something else.
Some Questions:
1. I write client Java File but whether i need to write server java file.
2. Can we send request by using ip and port.
3. Can we use host name.
4. Any echo server name? i need to send message to this server want to know response.
5. I try both server,java and client.java then i got result? is this solution for me.
1. I write client Java File but whether i need to write server java file.
Yes, you either need to write your own server (if the server should fulfill some unique requirements) or connect to an existing one. The message "connection refused" indicates that no server is running at the port you are trying to connect to.
2. Can we send request by using ip and port.
Yes.
3. Can we use host name.
Yes. You need either IP or hostname, and the port.
4. Any echo server name? i need to send message to this server want to know response.
You can setup an echo server on your machine so that you can first focus on coding your client. There is a Standard Echo server defined at port 7. Setup depends on your operating system environment - On Ubuntu Linux, I had to install the xinetd package and enable the echo server in /etc/xinetd.d/echo. Then, you can verify if the server is running by using the telnet program:
andreas#ubuntu:~$ telnet localhost 7
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello
Hello
Using telnet to connect to any port is also a common technique to verify if a server is running and reachable. With the example from your question, you could check with telnet 127.0.0.1 10008 whether a server is running on the port you specified - you will get the same connetion refused as from your Java program if no server is available.
5. I try both server,java and client.java then i got result? is this solution for me.
Not sure which server and client you are referring to.
Some additional references:
All about sockets (also includes "Writing a Client/Server pair")
Enabling desired xinetd protocols
Java Tutorial: Echo client in Java
You have to run your server program also in local host. You are getting this exception because of 10008 port not ruining on your machine.
Some Question:
I write client Java File but whether i need to write server java file.
either you can write a server program or you can connect to a remote server. In that
case you should have both ip and running port in remote server.
Can we send request by using ip and port.
Yes You required both to send a message.
Can we use host name.
If you machine can resolve your host name you can do it. Otherwice you can use ip address
Any echo server name? i need to send message to this server want to know response.
I have no idea about this , need to search on web.
I try both server,java and client.java then i got result? is this solution for me.
Yes.
I have this small test socket connection class:-
import java.net.Socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
public class TestTelnet {
public static void main(String args[]) throws Exception {
Telnet telnet = new Telnet();
Socket socket = null ;
socket = new Socket("localhost", 23);
socket.setKeepAlive(true);
BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println(r.readLine());
socket.close();
}
}
It works perfectly well when I use another port (for example 25 for SMTP) and the println of r.readLine works brilliantly. I can also connect to port 23 via the command prompt (telnet localhost 23) and I get the following returned:-
Ubuntu 8.10
my-laptop login:
But when I try and connect to port 23 using my java class, it just hangs on the readLine println. Does anyone know why this is?
I guess it's because your expecting a line (with CR or CRLF termination) but your telnet service does not send a complete line. Try using r.read() instead of r.readLine()
Telnet is a protocol, and is probably expecting you to do option negotiation. Once you send it something useful, it will probably send you something useful.
see: http://www.faqs.org/rfcs/rfc854.html
Telnet is both a protocol and an application
When you use telnet the application to a machine, the application sends the protocol information so the remote machine may respond.
Since you say it stay there, it means it is working, it's just you are not following the protocol.
The protocol is described here:
https://www.rfc-editor.org/rfc/rfc854
What you're trying to do here is write a telnet application.
A good example of a Telnet client can be found at http://www.java2s.com/Code/Java/Network-Protocol/ExampleofuseofTelnetClient.htm