I have created a server in java which accepts client connections. But I am able to only connect one client
class Server extends Thread{
private void startServer() {
try{
ss=new ServerSocket(3000);
s=ss.accept();
DataRead d1=new DataRead();
d1.t.start();
}catch(Exception er){
er.printStackTrace();
}
}
}
You only ever accept one socket. In your jButton1ActionPerformed you have
s=ss.accept();
But that is only invoked once, when you click the jButton1 button. You need to keep calling accept() to if you want to have multiple clients able to connect.
Also, keep in mind that each call to accept() will block until a client connects and then return a new socket, representing that connection. So if you want to support multiple client, you shouldn't have your Socket as a global variable, it should instead be included in the constructor of your DataRead class, so each reader operates on a unique socket/connection/client.
Related
I'm new to socket programming, I have problem in understanding serversocket.
assume we create a serversocket like this:
loadbalancerSocket = new ServerSocket(port, 20);
connection = loadbalancerSocket.accept();
and then after some stuff, write something in its buffer:
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
writer.write("Hello!");
writer.flush();
writer.close();
My question is : How the connection understand which client should get the response of server? our backlog is 20 , and 20 client can connect to the server socket at the same time(As I understood).
In your example the first connected client gets the response. The backlog parameter does not mean number of clients that can connect in parallel. It is the maximum number of clients waiting for accepting connection.
The ServerSocket is not connected to any particular client. The connected socket is the socket returned from accept(). If you want to handle multiple clients in parallel you have to call accept() multiple times and handle connections separately. You can create a special thread for each connection for example.
accept() is typically called in a loop and the newly created connected socket returned from accept() is typically passed to a handler that is responsible for particular client.
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 have implemented a socket with a server and single client. The way it's structured currently, the server closes whenever the client closes. My intent is have the server run until manual shutdown instead.
Here's the server:
public static void main(String args[])
{
;
try
{
ServerSocket socket= new ServerSocket(17);
System.out.println("connect...");
Socket s = socket.accept();
System.out.println("Client Connected.");
while (true)
{
work with server
}
}
catch (IOException e)
{
e.getStackTrace();
}
}
I've tried surrounding the entire try/catch loop with another while(true) loop, but it does nothing, the same issue persists. Any ideas on how to keep the server running?
It looks like what's going to happen in your code there is that you connect to a client, infinitely loop over interactions with the client, then when someone disrupts the connections (closes clearning, or interrupts it rudly - e.g., unplug the network cable) you're going to get an IOException, sending you down to the catch clause which runs and then continues after that (and I'm guessing "after that" is the end of your main()?)...
So what you need to do is, from that point, loop back to the accept() call so that you can accept another, new client connection. For example, here's some pseudocode:
create server socket
while (1) {
try {
accept client connection
set up your I/O streams
while (1) {
interact with client until connection closes
}
} catch (...) {
handle errors
}
} // loop back to the accept call here
Also, notice how the try-catch block in this case is situated so that errors will be caught and handled within the accept-loop. That way an error on a single client connection will send you back to accept() instead of terminating the server.
Keep a single server socket outside of the loop -- the loop needs to start before accept(). Just put the ServerSocket creation into a separate try/catch block. Otherwise, you'll open a new socket that will try to listen on the same port, but only a single connection has been closed, not the serverSocket. A server socket can accept multiple client connections.
When that works, you probably want to start a new Thread on accept() to support multiple clients. Simplest way to do so is usually to add a "ClinentHandler" class that implements the Runnable interface. And in the client you probably want to put reading from the socket into a separate thread, too.
Is this homework / some kind of assignment?
I'm currently involved in a project at school in which we are building a communication system to be used on Android phones. For this, we will be using a server which opens sockets towards all clients, making them communicate.
I've done several chat applications before without any problems with sockets or thread handling but this time, for some reason, it boogles my mind.
The problem is that the application starts to listen as soon as I initiate the ServerSocket object, serverSocket = new ServerSocket(5000), and not at the serverSocket.accept().
Why is that?
As soon as I use the following method:
public void startListen(String port) {
try {
serverSocket = new ServerSocket(Integer.parseInt(port));
portField.setEditable(false);
} catch (IOException e) {
printMessage("Failed to initiate serverSocket: " + e.toString());
}}
The port is showing up as Listening in the command prompt (using netstat). If I don't call it, the port is not listed as listening.
TCP 0.0.0.0:5000 Computer:0 LISTENING
So, is here anything I'm missing when using the ServerSocket object? My older programs using ServerSocket doesnt start listening until I call accept().
If you're talking about the Java ServerSocket, there's no listen method for it, presumably since it's distinct from a client-side socket. In that case, once it has a port number (either in the constructor or as part of a bind), it can just go ahead and listen automagically.
The reason "regular" sockets (a la BSD) have a listen is because the same type is used for client and server, so you need to decide yourself how you're going to use it. That's not the case with ServerSocket since, well, it's a server socket :-)
To be honest, I'm not sure why you'd care whether or not the listening is active before accept is called. It's the "listen" call (which is implicit in this class) that should mark your server open for business. At that point, the communication layers should start allowing incoming calls to be queued up waiting for you to call accept. That's generally the way they work, queuing the requests in case your program is a little slow in accepting them.
In terms as to why it does it, it's actually supposed to according to the source code. In the OpenJDK6 source/share/classes/java/net/ServerSocket.java, the constructors all end up calling a single constructor:
public ServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException {
setImpl();
if (port < 0 || port > 0xFFFF)
throw new IllegalArgumentException(
"Port value out of range: " + port);
if (backlog < 1)
backlog = 50;
try {
bind(new InetSocketAddress(bindAddr, port), backlog);
} catch(SecurityException e) {
close();
throw e;
} catch(IOException e) {
close();
throw e;
}
}
And that call to bind (same file) follows:
public void bind(SocketAddress endpoint, int backlog) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
if (!oldImpl && isBound())
throw new SocketException("Already bound");
if (endpoint == null)
endpoint = new InetSocketAddress(0);
if (!(endpoint instanceof InetSocketAddress))
throw new IllegalArgumentException("Unsupported address type");
InetSocketAddress epoint = (InetSocketAddress) endpoint;
if (epoint.isUnresolved())
throw new SocketException("Unresolved address");
if (backlog < 1)
backlog = 50;
try {
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkListen(epoint.getPort());
getImpl().bind(epoint.getAddress(), epoint.getPort());
getImpl().listen(backlog);
bound = true;
} catch(SecurityException e) {
bound = false;
throw e;
} catch(IOException e) {
bound = false;
throw e;
}
}
The relevant bit there is:
getImpl().bind(epoint.getAddress(), epoint.getPort());
getImpl().listen(backlog);
meaning that both the bind and listen are done at the lower level when you create the socket.
So the question is not so much "why is it suddenly appearing in netstat?" but "why wasn't it appearing in netstat before?"
I'd probably put that down to a mis-read on your part, or a not-so-good implementation of netstat. The former is more likely unless you were specifically testing for a socket you hadn't called accept on, which would be unlikely.
I think you have a slightly wrong idea of the purpose of accept. Liken a ServerSocket to a queue and accept to a blocking dequeue operation. The socket enqueues incoming connections as soon as it is bound to a port and the accept method dequeues them at its own pace. So yes, they could have named accept better, something less confusing.
A key reason may be myServerSocket.setSoTimeout(). The accept() call blocks - except if you define a timeout before calling it, then it only blocks for that duration and afterwards, harmlessly (i.e. ServerSocket is still valid), throws a SocketTimeoutException.
This way, the thread stays under your control ... but what happens in those milliseconds while you're not in your temporarily blocking accept() call? Will clients find a listening port or not? - That's why it's a good thing the accept() call is not required for the port to be listening.
The problem is that the application starts to listen as soon as I
initiate the ServerSocket object, serverSocket = new ServerSocket(5000), and not at the serverSocket.accept().
I'm thankful for this question (-> upvote) because it's exactly this behavior I wanted to know about, without having to do the experiment. Google-term was 'java serversocket what happens if trying to connect without accept', this question was in the link list of the first hit.
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()?