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.
Related
I am writing an application that streams data that clients can then listen to and receive. However I am running into an issue with closing a socket when a client is no longer listening.
What I do is create a ServerSocket, when then waits for a connection and once it is connected, I start streaming the data. However, once the client is no longer connected, I am stuck in a loop of streaming and cannot tell if anyone is listening. Is there a way around this?
try {
serverSocket = new ServerSocket(STREAM_PORT);
Socket clientSocket = serverSocket.accept();
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(), true);
while (true) {
pw.println("some data");
}
} catch (SocketException e) {
// Never occurs when client disconnects
} catch (IOException e) {
// Never occurs when client disconnects
}
I have tried using socket.isClosed(), but it always returns false. Am I approaching this from the wrong angle, or is there a way to do it. I would ideally not want the client to have to send the server a "end" command.
EDIT: Edited to reflect what current code I am running after #Rod_Algonquin suggestion
As you are using PrintWriter, which swallows I/O exceptions, you need to call checkError() after each write to see if an error has occurred.
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 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.
I'm programming a client server app. I'm wondering to end the connection, which side should decide to end it, client or server?
Then if for example the client did it, should the server still keep open or not?
Suppose we have the below codes for each client and server:
socket = new Socket("127.0.0.1",3000);
........
socket.close();
or
serverSocket = new ServerSocket(3000);
socket = serverSocket.accept();
......
serverSocket.close();
EDIT:
according to the matt's answer, i pot my code here and let see why my code doesnt work:
generally, i have a Jframe program as client which will connect to a server and while its open, i want the connection being alive, since it send info to the server and server should response for the result. but if i dont use closing the socket from server it gives an error and if i use, after once calculation, it closes the connection:
Server
private static PrintWriter toClient;
private static BufferedReader fromClient;
public static void run() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException
{
System.out.println("Server is waiting for connections...");
while(true)
{
openStreams();
processClient();
closeStreams();
}
}
OpenStream:
public static void openStreams() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException
{
serverSocket = new ServerSocket(3000);
socket = serverSocket.accept();
System.out.println("Connected");
toClient = new PrintWriter(socket.getOutputStream(),true);
fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
Closestearms:
public static void closeStreams() throws IOException
{
fromClient.close();
toClient.close();
socket.close();
serverSocket.close();
System.out.println("Disconnected");
}
the error i receive if i remove the closestream();
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at java.net.ServerSocket.<init>(ServerSocket.java:185)
at java.net.ServerSocket.<init>(ServerSocket.java:97)
Depends on your application's logic. Both are valid, and you must make sure your code is correct in both cases, since if the connection is broken "involuntarily" (like a network drop), it will appear to both sides as if the other side had closed the connection.
So your code must handle both cases gracefully.
Your closing code is suspicious: you're closing the listening socket, which is unusual. You should only close the listening socket when you don't want any more incoming connections (i.e. usually for a server, when you're shutting down the server).
Only close the socket you got from accept to end that "conversation", and don't re-open the server listening socket. (The exception you're getting might be an "Address already in use" in this case. See How to set reuse address option for a datagram socket in java code? for an example of how to avoid that specific problem.)
Either end may close the connection - neither is "more correct".
However, it is important to clear up one (seeming) misunderstanding in your code:
closing the ServerSocket is not closing the socket that represents the connection between the two end points.
The ServerSocket is a listening socket on a port. When a client makes a connection to the ServerSocket on that port, a (normal) Socket is returned by the ServerSocket.accept() method. Communication between your two end points uses the input and output streams associated with this (normal) Socket.
Closing the ServerSocket just stops listening on the well known port and doesn't relate to the established sockets.
The socket is present in both the client and server program. Closing any socket will throw exception on the other side.
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()?