How to run a simple socket server that allows incoming connections? - java

I am trying to build a very simple socket server in JAVA that my Flash application can listen to. I am using this tutorial. Everything seems to be working - the JAVA code is compiled and the server is running.
My question is: how can external applications send messages to this server using just an IP address and a port number? My goal is that flash can listen to socket messages sent by an external application.
The Java code:
import java.io.*;
import java.net.*;
class SimpleServer {
private static SimpleServer server;
ServerSocket socket;
Socket incoming;
BufferedReader readerIn;
PrintStream printOut;
public static void main(String[] args) {
int port = 8080;
try {
port = Integer.parseInt(args[0]);
} catch (ArrayIndexOutOfBoundsException e) {
// Catch exception and keep going.
}
server = new SimpleServer(port);
}
private SimpleServer(int port) {
System.out.println(">> Starting SimpleServer");
try {
socket = new ServerSocket(port);
incoming = socket.accept();
readerIn = new BufferedReader(
new InputStreamReader(
incoming.getInputStream()));
printOut = new PrintStream(incoming.getOutputStream());
printOut.println("Enter EXIT to exit.\r");
out("Enter EXIT to exit.\r");
boolean done = false;
while (!done) {
String str = readerIn.readLine();
if (str == null) {
done = true;
} else {
out("Echo: " + str + "\r");
if(str.trim().equals("EXIT"))
done = true;
}
incoming.close();
}
} catch (Exception e) {
System.out.println(e);
}
}
private void out(String str) {
printOut.println(str);
System.out.println(str);
}
}

Maybe I don't understand correctly your problem description, but if you create the server in Java, it listens to its port and not your Flash application. If you want your Flash application to wait for messages from other applications, it must have a server role and listen to a TCP port the same way as this Java server does.
You can connect to and test the given Java server easily by telnet program (available in all operating systems) by providing a host name or an IP address and a port as parameters:
telnet 127.0.0.1 8080
Any other application can connect in a similar way, using just a hostname/IP address and a port. For example in Java, you can create a client socket:
Socket clientSocket = new Socket("localhost", 8080);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

By not specifying an IP address for your socket, it will listen on 0.0.0.0 (all interfaces).
In fact, that will usually be your computer's IP / the server's IP.
Assuming that your application runs on your computer at home, there are three cases that cover most of the connection situations:
Connecting from the same machine:
Use 127.0.0.1:8080
Connecting from the same LAN (e.g. your brother's PC):
Use your LAN IP (e.g. 192.168.1.4:8080)
Connecting from WAN (outside your routers LAN) (internet e.g.):
Use your WAN IP.(e.g. 84.156.74.194). There are plenty websites, that tell you your WAN IP like this
You may have to setup your router, to forward the port 8080 to your PC
For simple connection tests, one could use a telnet client.

I think you are missing the point of client/server socket applications.
If you are building the socket server (with whatever programming language you chose), you will then need to connect with (a) socket client(s) to this server. After a connection is successfully established (persistent) between the client and the server, you can start what ever kind of communication you have implemented between them.
The server always acts as the passive, the client as active part in a socket server/client constellation.

I was checking the link that you are referring to. In that, the procedure to create a stand-alone server is mentioned which is the code that you have pasted as well.
According to the link, the application acts as the client and uses the XMLSocket methods to connect to this server. This application is the flash application that you are talking about. As mentioned in the link, by using the following code any flash application can connect and talk to the server:
var xmlsock:XMLSocket = new XMLSocket();
xmlsock.connect("127.0.0.1", 8080);
xmlsock.send(xmlFormattedData);
When you mention
My goal is that flash can listen to socket messages sent by an external application.
its actually the flash application that is the client and it cannot listen unless programmed to act as a server. I hope this provides some clarity!

Related

Socket connection won't work between smartphone and computer

I have a C# WPF application that uses TCPListener to start a Server in my computer, and an android app that works as a client. It works perfectly when I start the server and emulate the app in my computer, but most of the time it just doesn't work when I use my smartphone to connect to my computer, it only works some times after I restarted my router DHCP and my smartphone.
If you need, here's the connection code
Server:
private static IPAddress ipAd;
private static TcpListener server;
private static TcpClient client;
public static void start() {
//Already tried with both
ipAd = IPAddress.Parse(TCPServer.GetLocalIPAddress());
//ipAd = IPAddress.Parse("127.0.0.1");
server = new TcpListener(ipAd, 1209);
client = default(TcpClient);
try {
server.Start();
Console.WriteLine("Server started");
} catch {
Console.WriteLine("Failed to start server");
}
Client:
Socket socket = null;
String response = new String();
try{
//connect This ipAddress is the same in my desktop
InetAddress ipAd = InetAddress.getByName(ipAddress);
socket = new Socket(ipAd, 1209);
//send
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.write(message.getBytes());
}
...
Thanks for your time, I've should had dedicated more to my Computer Networks class...
Should I redirect some specific port? Have some specific configurations in my router/firewall? I think I'm missing something
This would work when your devices located in the same network in terms of IP routing. However even part of the most simple SOHO grade WiFi routers/AP enable so called device isolation, denying access from wifi devices in the network access between them or to clients, connected with ethernet.
To make this setup work reliably you need to ensure the following:
Use external address of your router in the mobile application. (You can discover it browsing http://whatismyip.org from the server)
Setup port forwarding in your router for particular port to particular IP in your internal network.
As for privided source code, you'd rather use 0.0.0.0 as bind address in the server app, because default .NET implementation will select first available IP address and it may be not the one you're using for connection in the mobile app or not related to the same network. This approach may have security and convenience (coexistence) problems in case of complex networking setup, but will work good for most of the cases.

Java Socket connecting to a public ip-address

I need to make a server and client that connects to the server.
Problem: "the server works. the client can only connect to localhost, it cannot connect to a server on the internet. I want the client to connect to the server, via a public ip-address that the server is hosted on."
First of all, I have made sure that the port is forwarded and reachable i have tested the port, secondly i have disabled firewall completely from the server machine.
below is the test code i am using:
The Server: nothing fancy just simple - terminates if a client is connected, else just awaits a connection.
public class Server {
public static void main(String args[]) {
try {
ServerSocket srvr = new ServerSocket(52000);
srvr.accept();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
The Client: I have used no-ip.com to mask the ip of the server to "biogenserver2.noip.me".
Using .getCanonicalHostName(); will return the ip.
public class Client {
public static void main(String args[]) {
try {
String ip = Inet4Address.getByName("somets.noip.com").getCanonicalHostName();
InetSocketAddress sa = new InetSocketAddress(ip, 52000);
//Socket skt = new Socket("0.0.0.0", 52000); //local - this works fine.
Socket skt = new Socket();
skt.connect(sa);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
When i run this the server connects fine, but the client returns a "connection timeout" exception
Any help will be appreciated. Thanks.
Answer:
"Just for clarity: You have checked the port is open via public IP as returned by no-ip and the server will quit without exception when you run that little testclient (on a machine that is not the server machine) - is that correct?" – Fildor
TL:DR
Don't run the client and server on the same machine and the same network trying to connect to your server through your public ip then to your own local network will result in a client timeout exception
I was running the client and server on the same machine and also the same network. This caused the client timeout exception. I tried running the Client on a different machine and a different network and i was able to connect successfully.
What version of IP protocol your application uses? On linux, you may figure it out with netstat -tunap | grep 52000 and watching whether first field is tcp or tcp6. If latter, then it is possible that problem with IPv6 connectivity exists and you may want to prefer using IPv4 to IPv6 by specifying -Djava.net.preferIPv4Stack=true to JVM.

Why my chat application that does not work behind a router?

I developed a chat application Java/Socket(TCP), it works perfectly on my local network,however when i put it behind a router it does not work...
I have already tested the open ports on my router at:
http://www.yougetsignal.com/tools/open-ports/
the result is as follows
80 (HTTP)is open
21 (FTP)is open
22 (SSH)22 is open
23 (TELNET)is open
25 (SMTP)25 is open
.
.
.
I started my server with this list of ports(java -jar server.jar 23) :
int port=Integer.parseInt(args[0]);
ServerSocket serverSocket = null;
serverSocket = new ServerSocket(port);
System.out.println("server started at " + port);
Socket clientSocket = null ;
// repeatedly wait for connections, and process
while (true) {
try {
clientSocket = serverSocket.accept();
} catch (IOException ex) {
System.out.Println("error");
}
System.err.println("new client connected!");
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())),true);
String s;
while ((s = in.readLine()) != null) {
out.println("from server: "+s);
}
// colse all
out.close();
in.close();
clientSocket.close();
then Then with a simple client I tried to connect => anything received....
where does the problem? so how Skype,Msn and others chat application works fine?
there is a solution to do that ?
PS:I put a simple code(echo server) that represents my real server so you understand my code quickly :).
My regards .
This is just a guess, did you go into your router's configuration utility and set it up to proxy (usually called port forwarding) telnet requests to the client? Your router may be listening on 23, but unless you're running the chat client on the router's firmware, I doubt it knows what to do with that traffic. Maybe I misunderstood your question though.
Just having a server running behind a router is not enough for an outside client to establish a connection. Whatever port the server is listening on, the router needs to have a Port Forwarding rule configured on it that forwards inbound traffic for that port to the machine the server is running on. The client then needs to connect to the port on the router's public IP so the router can then forward that traffic to the server.

Sockets in Java...?

I need to build an application which can receive data from over a network and use this data to do some unrelevant things with.
Here's a piece of code to make clear what I'm doing.
On the server side:
static Socket client = null;
static ServerSocket ss = null;
if (ss != null) {
ss.close();
}
ss = new ServerSocket(5513);
isrunning = true;
System.out.println("Waiting for client...");
client = ss.accept();
System.out.println("Client accepted.");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
And the client side:
Socket client = null;
PrintWriter out = null;
try {
client = new Socket("hostname", 5513);
out = new PrintWriter(client.getOutputStream(), true);
}
Please note that this is just a piece of the code. There are no errors in the code.
After running the server-sided piece of code, it correctly waits for the client to connect.
Now here comes the problem. As soon as I try to connect from the client side, I'm getting a "connection refused"-error.
HOWEVER, I found something on the internet whoch told me to try telnetting from the client side. For example, let the server-sided IP be 192.168.1.1. So, after using this command:
telnet 192.168.1.1 5513
I actually get a connection with the server. The command will launch an empty screen, and everything I manually type in the command line will be sent to the server-side after pressing enter (checked with debugging).
So, I can manually connect to the server-side and send some data, but my code refuses to connect.
Anyone who knows what I am doing wrong?
Is this the code you're actually using?
client = new Socket("hostname", 5513);
Try changing it to:
client = new Socket("192.168.1.1", 5513);
client = new Socket("hostname", 5513);
Hostname needs to represent the IP Address you're connecting to. If you're trying to connect to yourself, it would be "localhost"
Also, the server is not listening for the client AT ALL TIMES, there must be a while loop so the server listens and accepts connections.
while (true) {
client = ss.accept();
out = new PrintWriter(client.getOutputStream(), true);
//You should probably assign it to a seperate thread to handle stuff for this client
}
And I should explain on why you're getting that particular error. When something says that the connection is refused, it usually means that the IP Address you want to connect to knows your sending a connection and is blocking it because it was not listening for that connection. Basically, when the server closed, you stopped listening for the client, so anything that came in on that port would be blocked. Of course, the other case could be that Java was blocked on your firewall and an exception should be made for it. Although this is rarely the case if what you're trying to accomplish is over a LAN.
You're not actually using "hostname" in your Socket object in the client are you?
It should the 192.168.1.1.
Are you on Windows? and If so have you added java.exe and javaw.exe to Firewall with inbound and outbound enabled? and have you added a rule for 5513 to your Firewall?
If yes Windows but no Firewall settings, that's your answer, open up your Firewall.

how can make two clients chat with each other?

this is not my homework(my homework is just about doing chat with a client and server which it works correctly especially with your help[:-)]
but I want to make two clients chat with each other,I don't know that when i get text from the first one how can I send that text to the other client.would you please help me.thanks.
public class MainServer {
static Socket client = null;
static ServerSocket server = null;
public static void main(String[] args) {
System.out.println("Server is starting...");
System.out.println("Server is listening...");
try {
server = new ServerSocket(5050);
} catch (IOException ex) {
System.out.println("Could not listen on port 5050");
System.exit(-1);
}
try {
boolean done = false;
while (!done) {
client = server.accept();
System.out.println("Client Connected...");
BufferedReader streamIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter streamOut = new PrintWriter(client.getOutputStream(),true);
String line = streamIn.readLine();
if (line.equalsIgnoreCase("bye")) {
streamIn.close();
client.close();
server.close();
done = true;
} else {
System.out.println(line);
streamOut.println(line);
}
}
} catch (IOException e) {
System.out.println("IO Error in streams " + e);
}
}}
That's it, your two "clients" will both act as client and server :
Listening to incoming things on a socket and sending things over an other sockets.
On the server, you can keep a Set of all the clients that are currently connected to the server. The server should listen for messages (can do this with a ServerSocket, and clients connect with normal Sockets). Each time the server receives a message, it sends this message back to all clients in the Set, and the clients display the message.
EDIT: this is for a client-server system, where clients connect to a central server instead of directly to each other. If you want to do direct client-to-client, one of them will just have to act as the server, and you'll need to implement a chat UI in both.
Here is a very simple, ~100 line, GUI chat program.
Have a look at Building an Internet chat system.
This explains how to write simple Clients and a Server with Java.
Unless you want to get into really complicated P2P discovery protocols, you would have to have a server to act at least as an intermediary.
In order to establish a direct client to client connection, the clients would need to know each others IP addresses. To do this, each client would first connect and "register" itself with a central server.
When a client wants to talk to another client, it would ask for that client's address from the server, then establish a connection directly with that client. So each client is acting both as a client (establishing connections with the server and other clients) and as a server (accepting connections from other clients).
It seems simple in theory, but in practice it gets more complicated. For example, what if the client you want to connect to is behind a firewall? You could have a hole in the firewall for incoming connections to get through, or you could fall back to having the communication go through the server, or if one of the clients is behind a firewall and the other isn't, the server could mediate the connection in the opposite direction.
Basically, there are two approaches:
One Chat server that receives all messages and distributes/forwards them to the clients (xmpp/jabber works this way)
One server that connects clients directly. Like on peer-to-peer networks
Looking back at your previous work, I think, the first approach is more feasible.
The server will offer one port where new clients can connect. After a client requests to participate/use the server, there server spawns a worker thread with a server socket on a different (available) port number and tell the client that port number. This is the reserved communication channel for that client with the server.
The rest is pretty straightforward: a client can send a new chat message, the server will pick it up and send it to all connected clients.
If a client disconnects, the worker thread will close the socket, return it to the pool and terminate.

Categories