I've met a problem that when I process my data on my program, that the server may getoff its socket of my client program, but i need to catch this exception and reconnect it to run my program. i did not use the serverSocket but all use the Socket to create an object.
I need your help. the implement code in detail is welcome. thanks
You can't. You have to create a new one if you're the client, and just hope the client will do that if you're the server.
try to create new one with same ip and port
while (!socket.isConnected()) {
try {
socket = new Socket(inetAddress, port);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
Related
I have many clients that are waiting for server messages. So the client make accept() and wait for server. When server have messages, open a connection to the client and send messages, after that, close the communication and the cycle restart.
I've seen usually the inverse approach, where the server do accept() and client connect to it. I've wrote this code but the client (that do accept() ) is blocked on point 3 and the server (that create the connection to the client) is blocked on point 2.
Sure i have some problems in my code (dont know where), but... this is the correct way ?
The client (that do accept() and wait for new messages)
try {
System.out.println("Waiting..");
receiver = serverSocket.accept();
System.out.println("1");
ObjectInput fromServerReader = new ObjectInputStream(receiver.getInputStream());
ObjectOutputStream toServerWriter = new ObjectOutputStream(receiver.getOutputStream());
System.out.println("2");
toServerWriter.writeObject("dummy");
toServerWriter.flush();
System.out.println("3");
ScheduledEvent scheduledEvent = (ScheduledEvent) fromServerReader.readObject();
System.out.println("4");
receiver.close();
System.out.println("5");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// Should never happen
}
The server (that when have new message to send to client, create the
connection)
try {
InetAddress address = InetAddress.getByName(sendToUser
.getMachineName());
socket = new Socket(address, port);
log.debug("1");
ObjectOutputStream toClientWriter = new ObjectOutputStream(
socket.getOutputStream());
ObjectInputStream fromClientReader = new ObjectInputStream(socket.getInputStream());
log.debug("2");
String read = (String)fromClientReader.readObject();
log.debug("3");
// Compose the message
ScheduledEvent scheduledEvent = new ScheduledEvent();
scheduledEvent.setSubject(event.getSubject());
scheduledEvent.setMessage(event.getText());
log.debug("4");
toClientWriter.writeObject(scheduledEvent);
toClientWriter.flush();
log.debug("5");
socket.close();
log.debug("6");
} catch (UnknownHostException e) {
// TODO handle
e.printStackTrace();
} catch (IOException | ClassNotFoundException e) {
// TODO handle
e.printStackTrace();
}
In client code, instead of using
PrintWriter writer;
Use
ObjectOutputStream writer;
And then use
writer.writeObject("dummy");
writer.flush();
Try using println instead of write toServerWriter.println("dummy");. The server may be waiting for the newline character.
In this site use socket for send message to the server.
I haven't any Error in this project but I doesn't work and don't show nothings in avd, help me to run it. I think the port number or IP number is false and don't know what number is correct.
Did I need to install something?
try this in client.java
class ClientThread implements Runnable {
#Override
public void run() {
try {
socket = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress(SERVER_IP, SERVERPORT);
socket.connect(socketAddress);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}catch (IOException e1) {
e1.printStackTrace();
}
}
}
I am writing HTTP WEB SERVER code. In the mean while I have to code retry policy on using port, so that on that port server can listen client's request.
Normal Code:
serversocket = new ServerSocket(ServerSettings.port);
It throws Exception, if ServerSettings.port is not free.
Now, I want to add retry policy, if ServerSettings.port is not free, try other ports. For that I write one code, and code is a s follows,
Updated Code:
try {
serversocket = new ServerSocket(ServerSettings.port);
} catch (IOException io) {
try {
ServerSettings.port += 505;
serversocket = new ServerSocket(ServerSettings.port);
} catch (IOException io1) {
try {
ServerSettings.port += 505;
serversocket = new ServerSocket(ServerSettings.port);
} catch (IOException io2) {
log.info(new Date() + "Problem occurs in binding port");
}
}
}
But above one shows poor coding skills, and not professional one.
How can I write retry policy for ports in a professional way, so that server can listen on that port?
Logically, I think this will work (Correct me if there are any syntax typos):
ServerSocket serversocket;
boolean foundPort = false;
while (!foundPort)
{
try {
serversocket = new ServerSocket(ServerSettings.port); // If this fails, it will jump to the `catch` block, without executing the next line
foundPort = true;
}
catch (IOException io) {
ServerSettings.port += 505;
}
}
You could wrap it in a function, and instead of foundPort = true;, you would return the socket object.
I have two threads, one for reading, one for writing data through the same socket. When is problem with connection two threads catch exceptions and try reconnect.To do this they call the same methods
public synchronized void close_connection() {
try {
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
and after it second one to try establish connection:
public synchronized boolean connect() {
boolean result=true;
socket = new Socket();
try {
socket.connect(new InetSocketAddress(address, port), 500);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
} catch (IOException e) {
result=false;
}
return result;
}
The problem is how to avoid trying connect with server from two threads one by one immediatly (after connection error - for example afrter closing connection by server). I mean: if one thread tries do connection the second thread should know this and dosen't try do the same but wait for establish connection by first one (to avoid permanent fight threads problem disconnect,connect, disconnect, connect....). I've tried with synchronization but my experience is too small.
Regards,
Artik
You could try something like this:
while(not connected){
try reconnecting
if(success){
//Everything is ok, go on
} else {
//sleep for random period of time and retry
}
}
or you can implement the socket operations in an object and share that object between your threads using locks.
Use appropriate mutex locking. This will make sure only one thread will access the connect() portion of your code.
Sorry for question, but I'm totally noob in Java. What is the best practice to execute ServerSocket.close() when caught IOException from ServerSocket? According to docs, ServerSocket.close() throws IOException and compiler asks us to catch it. What is the proper way to close connection on IOException?
try {
server = new ServerSocket(this.getServerPort());
while(true) {
socket = server.accept();
new Handler( socket );
}
} catch (IOException e) {
if (server != null && !server.isClosed()) {
server.close(); //compiler do not allow me to do because I should catch IOExceoption from this method also...
}
}
Thank you!
That's ugly in Java. I hate it, but this is the way you should do it: Wrapping it into another try-catch:
try {
server = new ServerSocket(this.getServerPort());
while(true) {
socket = server.accept();
new Handler( socket );
}
} catch (IOException e) {
if (server != null && !server.isClosed()) {
try {
server.close();
} catch (IOException e)
{
e.printStackTrace(System.err);
}
}
}
If you are going to close the ServerSocket outside of the try{}catch{} anyways, you may as well put it in a finally{}
try {
server = new ServerSocket(this.getServerPort());
while(true) {
socket = server.accept();
new Handler( socket );
}
} catch (IOException e) {
// Do whatever you need to do here, like maybe deal with "socket"?
}
finally {
try {
server.close();
} catch(Exception e) {
// If you really want to know why you can't close the ServerSocket, like whether it's null or not
}
}
In Java SE 7 or later you can use try-with-resources statement, ServerSocket implements java.io.Closeable, so you don't need to explicitly #close() the socket when used in this way.
try (ServerSocket server = new ServerSocket(this.getServerPort())) {
while(true) {
socket = server.accept();
new Handler( socket );
}
} catch (IOException e) {
// It's already closed, just print the exception
System.out.println(e);
}
You can close the resources in the finally block,
http://download.oracle.com/javase/tutorial/essential/exceptions/finally.html
} finally {
try {
socket.close();
} catch(IOException e) {
e.printStackTrace();
}
}