How can a Server open a TCP connection through a Client which was connected to server before? Let say we have simple server like the code shows below; server waits for client connections and a handler thread serves connected clients. Client as below, every time wants to do an operation with the server, reestablish the connection, communicate with server and then close the connection. So, if server would like to open a TCP connection through the client(when there is no an active connection from client to server), how it can be done?
Server Code
public class DServer {
public static void main(String[] args) {
ServerSocket serverSocket = new ServerSocket(7800);
while(true) {
Socket socket = serverSocket.accept();
System.out.println("Server established a new connection");
HandleConnection handler = new HandleConnection(socket);
handler.start();
}
}
}
Client Code
public class DClient{
public static void main(String[] args) {
Socket socket = new Socket("localhost", 7800);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
//for every operation you do, first reestablish the connection,
//communicate with server, then close the connection.
}
}
I think you have some fundamental misunderstandings about what a client is and what a server is in a networking sense.
The server is the application listening for connections. The client is the application creating connections to the server. If you want both of your applications to be able to initiate communication at will, then your applications will need to be both clients and servers.
So your "DClient" application will need to have a ServerSocket. You "DClient" application can then inform your "DServer" application of it's host and port for when "DServer" wants to create a connection (note that things like NATing can make this sort of thing problematic if both applications are not in the same network).
Alternately, depending on your use case, you could just leave the connection from client to server open. This is the more usual approach to letting the server push data.
There is solution to create proxy server which is manage the both request client and server which called middleware for both client request.
In network programming it must required to fist server start and then client request because client server architecture.
Related
I am trying to build a socket that is capable of having multiple TCP connections, at different ports with multiple clients simultaneously.
The situation is my socket has to receive commands from a server and redirect the commands to wireless sensors (one command to one sensor, not broadcasting), and be able to collect the corresponding data from the sensors and then send them back to the server. Connections with the server would be using TCP, but connections with the sensors could be TCP or UDP.
My main concern are the TCP connections. I am looking into java multithreaded or thread pooled socket tutorials. But the examples I’ve seen were only using a single port to handle all the connections. I’m also trying to look into other possible solutions: utilizing tomcat server, java servlet/JSP, socket channel etc…
I’m not an expert in networking or socket programming so I really hope someone with experience could point me in the right direction. Thank you for any help you can provide in this situation.
Not sure if I fully understand but it seems like it is unnecessary for me to obtain multiple ports for my situation. Seems like I would need to focus on multi threaded sockets and Java NIO topics?
And again thank you for the advice and help.
This is rather a big project to be answered in full here. But here are some general guides:
1) If you want to create a socket on one port you need to create one thread to run it. That is called a server socket. Therefore, from the main thread u need to call one thread for every socket on every port.
2) Each server socket keeps listening on a certain port and waits for clients to connect.
when a client actually connects, the server socket should open another thread for that connection alone and return back to listening.
while(myServerSocket.accept())
{
Open connection thread
}
My advice would be to learn online about how to open threads from classes and then follow the guide above.
Unless you are going over 10k connections then most web servers would be able to handle the traffic.
But maybe you should get more details on the difference between a connection, a socket, and a port. Take a look at this: What is the difference between a port and a socket?
On your question: one port can handle many connections. You don't need different ports for different connections.
My understanding of this request is that you would need to deploy several instances of your server socket application listening on their respective ports and capable of servicing multiple client connections.
By way of mathematical induction, if you have written your server app properly it should work anywhere it is deployed. Below is sample of what your server socket application run should look like
public void run()
{
try
{
while(true)
{
try
{
Thread client_thread= new Thread(new ClientReqProcessor(serverSocket.accept()));
client_thread.start();
}
catch(Exception ex)
{
logger.error("connection error: "+ex.getMessage());
}
}
}
}
Why do you want to use multiple ports? You can have multiple connections on one listening port. The connection itself runs always on different ports.
while (running)
{
try
{
#SuppressWarnings("resource")
Socket socket = serverSocket.accept();
new ServerHandler(socket); // ServerHandler is your class to handle one connection.
}
catch (IOException e)
{
...
}
}
When you really need different ports, you can create a lot of Threads, each with a ServerSocket. Ports are one of the most limited resources on your computer. The running Threads are much cheaper.
for(int i = 1000; i < 1100; i++)
{
final int port = i;
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
new ServerHandler(socket); // ServerHandler is your class to handle one connection.
}
catch(IOException e)
{
...
}
}
}).start();
}
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!
I'm trying to develop a Java chat server. I don't know if the better solution is to do either of:
Create a socket for each client and keep it open
Set an interval in the client application and query a database to check if there are messages for the client.
Which is the best way to go for this situation?
i suggest you to learn Serialization if you want to develop an application with UI support. Moreover, you have to create a socket for each client especially in Server side. And a Server should have threads which maybe you can call client handler, to deal with clients' requests. Query a database for checking received messages is meaningless but you can save all messages in a database maybe. My advice is if you are going to use a database (well i suggest that), use it for dealing with registration process of clients. So whenever a client sends a request to server for logging in, a thread will check will check if that client has already have an account or not in database.If not you can implement a simple register form. And logically every client will have a friend list which you should keep them in a database.
EDIT: The Server will look like this.
public class Server {
public static void main(String[] args) {
try {
ServerSocket s = new ServerSocket(8087);
System.out.println("Server Started");
while (true) {
Socket incoming = s.accept();
System.out.println(incoming.getInetAddress().getHostAddress() + " was connected!");
new ClientHandler2(incoming).start();
}
} catch (Exception e) {}
}
}
So the main point is Server should never stop to listen the specified port.
Client Handler which is a thread created in Server side.
public class ClientHandler extends Thread {
private Socket incoming;
public ClientHandler(Socket incoming){
this.incoming = incoming;
}
#Override
public void run(){}
Server will send the initialized socket into the ClientHandler's constructor and call start() method to run it.
Actually you do not have to keep connection for eternity for each client ! All you have to do is store client's state server side and then communicate via any connection. Then you can get back resource and use them more wisely when your client doesn't seem to be active for a while.
What would this statement do:
ServerSocket ss=new ServerSocket(4646);
Please explain in layman terms.
The statement effectively tells the JVM to listen on port specified (4646) for incoming connections. By itself it doesn't mean anything since you will have to take incoming connections to that port and use them to build normal Socket objects that will be then used for ingoing/outgoing data.
You could say that the ServerSocket is the object through which real TCP sockets between clients and the server are created. When you create it, the JVM hooks to the operating system telling it to dispatch connections that arrive on that port to your program.
What you typically do is something like:
public AcceptThread extends Thread {
public void run() {
ServerSocket ss = new ServerSocket(4646);
while (true) {
Socket newConnection = ss.accept();
ClientThread thread = new ClientThread(newConnection);
thread.start();
}
}
}
So that you will accept incoming connections and open a thread for them.
Straight from the ServerSocket Java docs:
Creates a server socket, bound to the specified port.
What's a server socket?
This class implements server sockets. A server socket waits for requests to come in over the network. It performs some operation based on that request, and then possibly returns a result to the requester.
public ServerSocket(int port) throws IOException
documentation:
Creates a server socket, bound to the
specified port. A port of 0 creates a
socket on any free port.
That would bind your ServerSocket to port 4646 on the local machine.
You could then accept sockets on this connection with
// pick up server side of the socket
Socket s = ss.accept();
Now, your client can connect to your server, establishing a socket connection, like this
// pick up client side of the socket, this is in a different program (probably)
Socket connectionToServer = new Socket("myserver",4646);
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.