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);
Related
I am writing client/server application in which multiple clients connect to servers and continiusly send serialized objects to servers at a high rate over TCP connection.
I am using ObjectOutputStream.writeObject on client and ObjectInputStream.readObject at server.
Server application accepts clients connection on the single port using serverSocket.accept() and passes Socket to a new thread for reading objects.
When a single client connects and sends about 25K objects/s - all works fine. Once I start a second client, after the short period of time, one or both clients hang on ObjectOutputStream.writeObject for one of the servers and the corresponding server hangs on the ObjectInputStream.readObject.
No exceptions thrown on the both sides.
If rate is very low, lets say 10-20/s in total - it will not hang but at 100-1000/s it will.
Using netstat -an on the client machine I can see that the send-Q of the corresponding link is about 30K. On the server side the receive-Q is also ~30K.
When running client/server on the local Windows I observe something similar - client hangs but the server continue to process incoming objects and once it catches up, client unlocks and continue to send objects.
Locally on windows the server is slower than client, but on linux, number of the server instances running on the deferent machines is more than enough for the rate that clients produce.
Any clue what is going on?
client code snip:
Socket socket = new Socket(address, port);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
while(true)
{
IMessage msg = createMsg();
outputStream.writeObject(msg);
outputStream.flush();
outputStream.reset();
}
server code accepting connections:
while(active)
{
Socket socket = serverSocket.accept();
SocketThread socketThread = new SocketThread(socket);
socketThread.setDaemon(true);
socketThread.start();
}
server code reading objects:
public class SocketThread extends Thread
{
Socket socket;
public SocketThread(Socket socket)
{
this.socket = socket;
}
#Override
public void run() {
try {
ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
while(true)
{
IMessage msg = (IMessage)inStream.readObject();
if(msg == null){
continue;
}
List<IMessageHandler> handlers = handlersMap.get(msg.getClass());
for(IMessageHandler handler : handlers){
handler.onMessage(msg);
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
You have just described the operation of TCP when the sender outruns the receiver. The receiver tells the sender to stop sending, so the sender stops sending. As you are using blocking I/O, the client blocks in send() internally.
There is no problem here to solve.
The problem was that handlers on the server side were using some not thread-safe resources (like Jedis connection) so it was all stack on the server side.
Doing it thread safe solved the issue.
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.
Both ServerSocket and Socket have the method close() to close the socket.
What is the difference between the two?
Suppose, on the server side,
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
...
In this case, how is
socket.close();
different from
serverSocket.close();
if any?
TIA.
ServerSocket sets up a listener from which you can accept any number of Socket connections. Closing a Socket closes that one connection; closing the ServerSocket means the listener is closed and can no longer accept connections to that port.
java.net.ServerSocket
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.
java.net.Socket
This class implements client sockets (also called just "sockets"). A socket is an endpoint for communication between two machines.
In simple words, socket is from client side and serversocket is from server side
Check here
I'm trying to write a simple Java chat application in Server/Client.
I'm confusing in below method at server.accept() :
private void waitForConnection() throws IOException {
showMessage("Waiting for someone to connect... \n");
// `connection` is an instance of `java.net.Socket`
// `server` is an instance of `java.net.ServerSocket`
connection = server.accept();
showMessage("Now connected to " + connection.getInetAddress().getHostName());
}
Please tell me connection is equal to what?
And also server.accept() returns what?
Any helps would be awesome.
Assuming your server variable is a java.net.ServerSocket then the accept() method returns a java.net.Socket object.
From the returned Socket object, you have access to both the InputStream and OutputStream to read from and write to the connected client.
Your program should halt until a client connects. That's what the line connection = server.accept(); does. Returning type is a type of Socket, too.
That's the "connection" to your client, you can read from and write to.
Check this and that site to read more about network programming in Java.
when you do connections between two systems then you require a socket.
Socket of one system is connected with socket of another system. Both these sockets are connected via I/O stream. you can write to this stream and can read from this stream.
One system serves as server and another system serves as client .
As socket is combination of port no. and IP so server open its port no. and client try to connect with the server's IP and port no.
For connection to be maid the server accepts the incoming socket using accept() function. accept() function returns a local socket which is connected to another socket at the client..
accept() waits until a client socket arrives.
I want to write a server which listens on the given port for connections and puts sockets into BlockingLinkedQueue from which the consumer thread will read messages. I accept incoming connections in this way:
ServerSocket serverSocket = new ServerSocket(port);
while (true)
{
Socket socket = null;
socket = serverSocket.accept();
queue.put(socket);
}
When I try to connect in parallel from two separate hosts it occurs that responses to the first one are sent to the second one after establishing the second connection. When I change my code to this listed below the second connection is merely refused:
while (true)
{
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
queue.put(socket);
}
My questions are:
What's the difference between this two situations? Why in the first situation messages are sent to the second host?
How should I refactor my code in order to create separate connections between my server and both hosts and handle them in parallel?
What's the difference between this two situations?
In the first case, you are using the same port for multiple connections. In the second case, you are discarding the server port so any waiting connections for be refused.
Why in the first situation messages are sent to the second host?
Due to a bug in code, not shown here.
How should I refactor my code in order to create separate connections between my server and both hosts and handle them in parallel?
Create a thread for each connection.