I created a simple echo server in Java. When I try it locally, it works as it should. However, when I try to connect it from a different computer using the IP address and the port number the server is running on, it never connects. Is there anything else that should be done to connect to a server from a different computer?
import java.net.Socket;
import java.net.ServerSocket;
public class EchoServer {
public static void main(String[] args) throws Exception {
// create socket
int port = 4444;
ServerSocket serverSocket = new ServerSocket(port);
System.err.println("Started server on port " + port);
// repeatedly wait for connections, and process
while (true) {
// a "blocking" call which waits until a connection is requested
Socket clientSocket = serverSocket.accept();
System.err.println("Accepted connection from client");
// open up IO streams
In in = new In (clientSocket);
Out out = new Out(clientSocket);
// waits for data and reads it in until connection dies
// readLine() blocks until the server receives a new line from client
String s;
while ((s = in.readLine()) != null) {
out.println(s);
}
// close IO streams, then socket
System.err.println("Closing connection with client");
out.close();
in.close();
clientSocket.close();
}
}
}
Please check the following things.
Is the server computer behind a network proxy ?
Does it have an independent public IP Address by which it is accessible from
anywhere ? Or, does it have an internal IP, by which it can be accessed in your LAN ?
Make sure FireWalls has an exception for port 4444. Or you may turn it of in both client and server.
If it does not help, post the exception you are getting (by editing the question). Or the server program is just freezing without any error ?
If this is on your LAN refer to the machine running your EchoServer by name (the actual machine name, I believe they show you to do it this way on the Sun Tutorial that posted this echo server excercise correct?). If that works it would help a lot in troubleshooting the issue.
Related
At this point, I am testing a webserver client/host system to be run on my raspberry pi (host) and on my pc (client). The basic idea is that every 5 seconds, the client on my pc sends a message to the host located at "192.168.0.11" at port 7051. It processes it and sends a message back to my pc.
For this I am using the following client code:
public static String getData() throws Exception {
try {
Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
socket.setReuseAddress(true);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int msg = 71;
out.write("TEALBEE_CUR:" + msg);
out.flush();
String input;
String data = "";
while ((input = in.readLine()) != null) {
data += input;
}
socket.close();
return data;
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
return null;
}
The problem here is that while data-flow is consistent and can run for at least a week; I lost use of other sockets connections on my pc, namely my Kodi remote control (this is media centre which I can control through a socket connection on my smartphone). My pc at address "192.168.0.37" accepts connections at port 193 for Kodi but after running the Java client for some time and sending a lot of requests to the server, I notice that the remote cannot connect anymore to my PC.
I thought that this might be the case because the sockets cannot be reused and after a single use the socket becomes unusable. This does seem to be the case as my host detects a different socket port for each request.
I tried to solve this by adding the code socket.setReuseAddress(true) and properly closing the socket after each message, but the problem still occurs.
How can I fix this properly (if possible only use one client socket and close this properly so it can be used again the next time).
EDIT: also important to note I can access 192.168.0.37:193 from my PC, but not from my smartphone when the socket connection cannot be established. Yes I am sure that the PC and smartphone and RPI are on the same network and without the client program running I CAN access 192.168.0.37:193 from my smartphone.
I'm trying to write an android app that interacts with a server. I'm trying now to write the server side with sockets. I created an instance of ec2 and ran it. I connected to it with putty and ran a simple "hello world" java program. Now I'm trying to run a server which use a socket, but I get this as the server socket: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=5667].
This is my code, very basic so far:
public class EchoServer {
public static void main(String[] args) throws IOException {
int portNumber = 5667;
System.out.println("server socket main");
try (ServerSocket serverSocket = new ServerSocket(portNumber);
) {
System.out.println(serverSocket.toString());
} catch (IOException e) {
System.out
.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
What should I do to run the server so I could connect to it via my andriod device?
Thanks!
You are on the right track. 0.0.0.0 simply means:
A way to specify "any IPv4-interface at all". It is used in this way when configuring servers (i.e. when binding listening sockets).
Next, your server will need to listen for incoming connections by using SocketServer.accept().
And then of course you'll want to receive and send data on the socket. This tutorial should help.
Finally, if you plan on serving multiple clients simultaneously with your server, you will want to consider concurrency and scalability, and perhaps consider using a framework like Netty.
Good Day,
I was taking a look at this tutorial to do a TCP Threadpool server.
http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html
It works great for listening/RECEIVING to clients and processing, and returning a response. There is a class inside that I pass in WorkerRunnable into, and that basically prints out the remote socket address (who it was sent from)
public void run(){
synchronized(this){
this.runningThread = Thread.currentThread();
}
openServerSocket();
while(! isStopped()){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
} catch (IOException e) {
if(isStopped()) {
System.out.println("Server Stopped.") ;
return;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
this.threadPool.execute(
new WorkerRunnable(clientSocket,
"Thread Pooled Server"));
}
this.threadPool.shutdown();
System.out.println("Server Stopped.") ;
}
The problem is. The remote address is supposed to stay fixed (I am working within my own home wifi router). However, the IP address of the sender stays the same, but the port keeps changing!!
This is a big problem for me..as I need to be able to return a response to the user for future tasks and I actually save this address to use again to send data. When I ran this in a single TCP thread..it stayed fixed (the port).
Why does the threadpool cause the TCP remote address port to keep changing?
With TCP, the client socket port is most of the time (almost 99%, except for specific protocols) randomly chosen. But to you don't have to know it, the only thing you have to do is to keep the clientSocket reference to write back data to the client. If you want to send data to the other host after that the connection is closed, you have to start a ServerSocket on both sides with a fixed port.
Even if you test from same machine the client port will be random by default. I am not sure if there is any way to set the client source port. However, if you use netstat or capture the packet you can be sure the source port is different for every connection.
I would like to create a program that will emulate a device connected to the network and send signals through a specific port.
The device is connected to the network and sends data through a port. On the server(or computer) I have running the CPR Manager v.4.3.0.1 from Lantronix that will associate the IP:PORT to a virtual COM port on the computer. I have a java program that listens to the COM ports and performs an action, this works great with the device.
I tried writing a java app using the Socket class to perform the connection but it was un successful, on the CPR side it only registers a Disconnect when the very first line is executed:
Socket socket = new Socket("192.168.1.160", 8888);
I also tried it using the UDP method and no message whats so ever is recorded.
Any help would be greatly appreciated. Also if there is no possible solution for Java then any other language would do fine.
EDIT:
Here is the Java code where I am attempting to send the data
public static void main(String[] args){
try{
Socket socket = new Socket("192.168.1.160", 8888);
if(socket.isConnected()){
System.out.println("It is connected.");
socket.setKeepAlive(true);
System.out.println(socket.isBound());
}else{
System.out.println("It is not connected.");
}
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String msg = "32";
for(int i = 0; i < 50; i++){
out.println(msg);
}
//Receive a reversed message
msg = in.readLine();
System.out.println("Server : " + msg);
}catch(Exception ioe){
ioe.printStackTrace();
}
}
Thanks.
Update
I got in contact with some people of the devices and they showed me that there is a way to communicate straight via a TCP/IP connection sending there ASCII Command Protocols. This would allow more in depth control at every level.
So, now I am writing a java program that can communicate using these protocols.
Because, I am not using a comm port anymore I am tying to emulate the baud rate, data bits, stop bit stuff. I will post when I have some that works.
Thanks for all the help.
if the product you are using is forwarding the traffic to a COM port should you be listening on the COM port not on a network connection. Sockets are for network traffic. A quick google search resulted this for me.
How to send data to COM PORT using JAVA?
Maybe that will help?
I try to play with sockets a bit. For that I wrote very simple "client" and "server" applications.
Client:
import java.net.*;
public class client {
public static void main(String[] args) throws Exception {
InetAddress localhost = InetAddress.getLocalHost();
System.out.println("before");
Socket clientSideSocket = null;
try {
clientSideSocket = new Socket(localhost,12345,localhost,54321);
} catch (ConnectException e) {
System.out.println("Connection Refused");
}
System.out.println("after");
if (clientSideSocket != null) {
clientSideSocket.close();
}
}
}
Server:
import java.net.*;
public class server {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(12345);
while (true) {
Socket serverSideSocket = listener.accept();
System.out.println("A client-request is accepted.");
}
}
}
And I found a behavior that I cannot explain:
I start a server, than I start a client. Connection is successfully established (client stops running and server is running). Then I close the server and start it again in a second. After that I start a client and it writes "Connection Refused". It seems to me that the server "remember" the old connection and does not want to open the second connection twice. But I do not understand how it is possible. Because I killed the previous server and started a new one!
I do not start the server immediately after the previous one was killed (I wait like 20 seconds). In this case the server "forget" the socket from the previous server and accepts the request from the client.
I start the server and then I start the client. Connection is established (server writes: "A client-request is accepted"). Then I wait a minute and start the client again. And server (which was running the whole time) accept the request again! Why? The server should not accept the request from the same client-IP and client-port but it does!
When you close the server , the OS will keep the socket alive for a while so it can tell the client the connection has been closed. This involves timeouts and retransmissions which can take some time. You might find some info here and here. If you want your server to be able to immediately rebind the same socket, call setReuseAddress(true) on it, though it might be the client sockets that's in a TIME_WAIT state.
The socket is no longer in TIME_WAIT state, and can be reused again by any program.
Your client code just connects, closes the socket and then exits. As far as the server/OS tcp stack is concerned, these are different connections - it's fine to reuse the source port as long as any prior connection have been torn down. (Note that the OS might not tear down all of the housekeeping of the connection immediately after you call .close() or your program exits, there's some time delay involved so it can be sure all packets have been sent/received)
It is likely the operating system has not yet shutdown the sockets, try the netstat command (should work on Windows or Unix/Linux). If you run it immediately after you close client or server you should still the socket in "TIME_WAIT" "CLOSE_WAIT" or something similar. You wont be able to reuse those ports until they are fully closed.
Per Question #3: Many clients can connect to a server attached to a single port. Apache runs on port 80 but that doesn't mean only one person can view your website at a time. Also you are closing your client socket before you're opening a new one.