Can anybody please explain me how this accept() method works.what does it return?does it creates a new socket on server side? does it returns the reference of the socket created on client side?i am so confused.it would be a great help if anyone could help.
ServerSocket.accept() waits/blocks until a client connects, establishes the connection and returns you the server-side Socket object which can be used to communicate with the client (client has a Socket object as well)
From Java API documentation of ServerSocket :
public Socket accept()
throws IOException
Listens for a connection to be made to this socket and accepts it. The
method blocks until a connection is made.
A new Socket s is created
and, if there is a security manager, the security manager's
checkAccept method is called with
s.getInetAddress().getHostAddress() and s.getPort() as its
arguments to ensure the operation is allowed. This could result in a
SecurityException.
Also you can find a good tutorial about it : here
From the javadoc:
public Socket accept() throws IOException
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
A new Socket s is created and, if there is a security manager, the security manager's checkAccept method is called with s.getInetAddress().getHostAddress() and s.getPort() as its arguments to ensure the operation is allowed. This could result in a SecurityException.
In short, if you set up your ServerSocket to listen on a particular port on your computer/device, it will automatically accept the first remote client that attempts to connect to it. A Socket is returned, which you can latch onto using its InputStream and OutputStream to send and receive data.
Related
This is my code when I run it in debug mode in eclipse it shows me that it doesn´t continue it stops a stays in the code where I have put an arrow.
private ServerSocket serverSocket = null;
private Socket socket= null;
private ObjectInputStream inputStream= null;
public void ConnectTCP(){
try{
serverSocket = new ServerSocket(5000);
---->socket = serverSocket.accept();
inputStream = new ObjectInputStream(socket.getInputStream());
System.out.print("Server is Running");
}catch(IOException e){
e.printStackTrace();
}
}
Your socket is already created at this line. Because server binds to a port, at the moment ServerSocket constructor is called. As for accept method, due to JavaDoc it
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
A new Socket s is created and, if there is a security manager, the security manager's checkAccept method is called with s.getInetAddress().getHostAddress() and s.getPort() as its arguments to ensure the operation is allowed. This could result in a SecurityException.
So, accept method is just waiting for client connections, that is the reason, why execution stops at this point. May be, it could be helpfull to read a java official tutorial for writing a server side.
Actually it won't stop, it waiting for connection.
When a client want to connect it then it connect with that socket and program flow goes next line.
I'm using Spring Integration on the server side to offer a socket. The socket as a defined soTimeout, so that exceeding that timeout will close the current open socket connection to the client.
TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
fact.setSoTimeout(timeout);
But the thread on the server side will continue. How can I force cancelation/termination of the server socket as well (maybe with an additional thread timeout, so that no thread can hang in the background by any issues)?
I presume you mean you want to stop listening for new connections when one of the client connenctions times out.
Implement ApplicationListener for TcpConnectionExceptionEvent and examine the exception; if it's a SocketTimeoutException, call close() on the server factory that was created by the factory bean.
I have a java server aplication which comunicate with multiple clients via SocketChannel. On this channel, client sends a request and server sends an answer. Now I want add feature that server can sends file to the client. I don't want send it via the socket whith I am using for comunication so is good idea to have more sockets between one client and one server? If yes how to handle them? Have I use something like this?
SocketChannel socket = serverSocket.accept()
if(!addressSet.contains(socket.address)) {
it is comunicate socket
}
else {
it is date transfer socket
}
or is there some better way?
Create a new ServerSocket on a random port once you accept a client connection, then tell him that port number. He should then connect to that as the data connection. Then,have the server accept one connection from it, which better be from him, then close that ServerSocket. It's not foolproof but it's reasonably strong.
Yes there is a better way.
Use ServerSocketChannel and the method public abstract SocketChannel accept() throws IOException
I create a new thread that runs the following code:
public static void startServer() throws IOException {
serverSocket = new ServerSocket(55000);
Socket clientSocket = serverSocket.accept();
}
The above code is run in a thread. Now, in my main class, I successfully create a socket
connection to the server and I have checked it's integrity which is fine. here is the code:
Socket testServerSocket = new Socket("127.0.0.1", 55000);
assertEquals("/127.0.0.1", testServerSocket.getInetAddress().toString());
assertEquals(55000, testServerSocket.getPort());
This runs perfect. Then, again from my main, I kill the server connection that closes the connection on the server side. However the following code keeps failing:
assertEquals(false, testServerSocket.isBound());
It keeps returning true. Likewise, if I check the remote IP address for the connection, it doesn't return null, but rather '/127.0.0.1'. Any ideas why this might be happening? Many thanks for your help
I'm not an expert on sockets (I know what they are, but haven't ever used sockets on Java, only with C on Linux), but like JavaDoc for java.net.Socket states, 'A socket is an endpoint for communication between two machines'. So while closing server-side socket does destroy the connection between the two sockets (server- and client-side), your client-side socket is still bound, hence the isBound() is returning true. Maybe you meant to call isConnected() or isClosed()?
I need a simple client-server communication in order to implement unit-test.
My steps:
Create server thread
Wait for server thread to put server socket into listen mode ( serverSocket.accept() )
Create client
Make some request, verify responses
Basically, I have a problem with step #2. I can't find a way to signal me when server socket is put to "listen" state. An asynchronous call to "accept" will do in this case, but java doesn't support this (it seems to support only asynchronous channels and those are incompatible with "accept()" method according to documentation).
Of cause I can put a simple "sleep", but that is not really a solution for production code.
So, to summarize, I need to detect when ServerSocket has been put into listen mode without using sleeps and/or polling.
The socket is put into listening state as soon as you construct the ServerSocket object, not when you call accept. As long as you create the client after the ServerSocket constructor has completed, you won't have a problem. Connections will be accepted and internally queued until accept gets called.
Here is some code to demonstrate:
ServerSocket serverSocket = new ServerSocket(12345);
Thread.sleep(10000);
Socket socket = serverSocket.accept();
During that 10 second gap before accept is called, the OS netstat command will show the server socket in "LISTENING" state, and clients can connect to it. If a client connects during that 10 seconds, the connection is queued, and when the accept method is finally called it immediately returns the queued Socket object.
Why not to send single just before calling accept()?
connectionAccepted = true;
loc.notify();
socket.accept();
To be sure that the socket is ready add a tiny sleep in your "client" code:
wait();
// we are here when notify is called.
Thread.sleep(10); // 10 ms
startTest();
You can even do better: create loop that tries to "ping" the socket with a tiny sleep between attempts. In this case you will start test as quickly as it is possible.