【问题标题】:How do I reconnect a client when server is down in Java?当服务器在 Java 中关闭时,如何重新连接客户端?
【发布时间】:2015-05-15 02:39:40
【问题描述】:

我有一个服务器,它在客户端连接时接受套接字。我希望能够关闭我的本地服务器并让我的客户端尝试重新连接大约 5 次,如果我启动我的服务器,客户端应该会指示您已重新连接。

我有点理解这是在try{} catch(IOException){Here goes the code for handleing reconnect} 中完成的,我想使用我第一次连接时使用的同一个套接字。我不想创建new Client,因为我必须重新输入用户名之类的东西

我尝试创建一个像clientSocket = new Socket("localhost", portnr) 这样的新套接字,但我不知道这是否是正确的方法。如果您有可以回答此问题的示例,请链接它们。我不介意阅读,只要它有良好的文档记录。提前致谢!

编辑。 这是我的客户类

public class Client {       

public static void main(String[] args) {        
    Client client = new Client();
    client.connect();
}
//------------------------------------------------------------

//METHOD CONNECT
//------------------------------------------------------------    
private void connect(){
    int reConnectTries = 0;
    Socket clientsocket;
    try {
        //------------------------------------------------
        //Sets up variables needded for execution            
        clientsocket = new Socket("localhost", 8900);
        DataOutputStream OUT = new DataOutputStream(clientsocket.getOutputStream());            
        ListenforMessages listen = new ListenforMessages(clientsocket);
        //We don't want to enter username all the time
        //So this goes not in the while-loop
        //------------------------------------------------
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Enter username");
        String username = keyboard.nextLine();
        //Sends username to sever so it can be added to a list
        OUT.writeUTF(username);
        //------------------------------------------------

        //------------------------------
        //Creates a thread to listen on messages from server(Other clients in this case)
        Thread trd = new Thread(listen);
        trd.start();
        //------------------------------            
        while (true) {   

            try {
                String sendMessage = keyboard.nextLine();
                OUT.writeUTF(sendMessage);                    
                OUT.flush();
            } catch (Exception e) {
                System.err.println("Could not send message to server. " + e);
            }
        }           
    } catch (IOException e) {
        System.err.println("Couldnt establish a connection: " + e);
    }        
}
//------------------------------------------------------------    

//CLASS FOR HANDLEING INPUT. We create a class for input on a new thread
//This is cause we don't want it to block other processes.
//----------------------------------------------------------------    
class ListenforMessages implements Runnable{

    Socket mySocket;
    DataInputStream IN;
    public ListenforMessages(Socket X) throws IOException {
        this.mySocket = X;
    }

    @Override
    public void run() {
        try {
            IN = new DataInputStream(mySocket.getInputStream());
            while (true) {                    
                System.out.println(IN.readUTF());   
            }
        } catch (Exception e) {
            System.err.println("Couldn't fetch message from server.Error: " + e);                
        }            
    }

}
}

【问题讨论】:

  • 1.相同的 Socket:所以在您的客户端中,使用 null 构造函数创建一个 Socket,并使用 connect 方法连接到服务器。然后,如果您断开连接,您可以再次使用connect。 2. 用户登录数据一次:在客户端捕获此信息,并在连接后以编程方式将其登录到服务器
  • 你的意思是 Socket clientSocket = new Socket() 然后是 clientSocket.connect("localhost", portnr) ?我将如何使用 connect 重新连接?
  • 我不明白 Bojje 的问题。您使用与第一次连接相同的方式进行操作
  • 要我添加代码,希望这样更有意义吗?
  • 哦,现在我明白你的意思了。看到我想要的是我必须自己实现的东西。我的问题是我的客户使用用户名被接受,没问题。但问题是我希望客户端使用相同的名称进行连接。

标签: java sockets client server reconnect


【解决方案1】:

对于这个问题有几个解决方案,但一个简单的解决方案是让客户端以设定的时间间隔尝试重新连接(打开到服务器的新连接)。例如,您可以尝试这样的操作,让您的客户端每 3 分钟尝试重新连接一次:

while(true) {
    try {
        clientSocket = new Socket("localhost", portnr);
        break; // We connected! Exit the loop.
    } catch(IOException e) {
        // Reconnect failed, wait.
        try {
            TimeUnit.MINUTES.sleep(3);
        } catch(InterruptedException ie) {
            // Interrupted.
        }
    }
}

这样,客户端会尝试连接,如果失败,等待3分钟再尝试。

【讨论】:

  • 是的,但是如果我只是打开一个新的套接字,我想回到断开连接的客户端。如果我重新连接,我不想创建一个新的 Client 对象。
  • TCP 中没有对此作出规定。如果您希望即使在断开连接后也能够暂停和恢复会话,那么您必须将自己作为协议的一部分来实现。
  • @Bojje 如何编码和重用Client 对象是您关心的问题。没有人强迫您使用任何特定的用法。但是你必须创建一个新的Socket.
  • @EJP 我在我的客户端类中编辑了问题。如果我无法连接到服务器,我想在第一个 try-catch 语句中执行一个while循环,并使用new Socket("localhost",portnr) 直到我可以连接。但是我不知道如何从那里去。如果我连接,我不想创建new Client。原因如果我这样做,我必须重新输入一个新的用户名。然后它变成了一个全新的客户,我不希望这样。
  • @Bojje 你正在创建一个Client 对象,在main() 方法中;那么你正在调用 Client.connect()。在connect() 方法中放置一个循环并不构成创建另一个Client 对象。你没有道理。
【解决方案2】:
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.NoRouteToHostException;
import java.net.SocketAddress;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.net.ConnectException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

final class TCPClient{

    private static Scanner in ;
    private static DataOutputStream douts;
    private static OutputStream outs;
    private static InputStream ins;
    private static DataInputStream dins;
    private static String ip;
    private static Integer port;
    private int count = 0;
    private static int times;

    public TCPClient(){
        serverConTest(port);
    }

    private boolean portIsOpenOrNot(String ip, int port){
        try{
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(ip,port),500);
            socket.close();
            return true;
        }catch(Exception e){
        }

        return false;
    }

    private void serverConTest(int port){

                while(true){
                    try{
                        InetAddress addr = InetAddress.getByName(ip);
                        SocketAddress sockaddr = new InetSocketAddress(addr,port);
                        Socket socket = new Socket();
                        System.out.println("Connecting To server...");
                        socket.connect(sockaddr);

                        Thread.sleep(1000);
                        boolean isactive = true;
                        if(portIsOpenOrNot(ip,port)){
                            outs = socket.getOutputStream();
                            douts = new DataOutputStream(outs);
                            System.out.println("Sending Request to server:");
                                while(isactive){
                                    Thread.sleep(1000);

                                    douts.writeUTF("Are you Alive..!");
                                    ins = socket.getInputStream();
                                    dins = new DataInputStream(ins);
                                    System.out.println("Response from server : "+dins.readUTF());
                                }
                        }

                    }catch(SocketException e){
                        System.out.println("Connection lost");
                    }catch(IOException e){
                        break;
                    }catch(InterruptedException e){
                        System.out.print("connection timeout in 50 second.");
                        break;
                    }
                }
    }

    public static void main(String[] args){
        in = new Scanner(System.in);
        System.out.print("Enter ip : ");
        ip = in.nextLine();
        System.out.print("Enter Port : ");
        port = Integer.parseInt(in.next());
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future future = executorService.submit(new Runnable() {
            public void run() {
                new TCPClient();
            }
        });

        try{
            future.get(50, TimeUnit.SECONDS);
        }catch(InterruptedException e){

        }catch(ExecutionException e){

        }catch(TimeoutException e){
            executorService.shutdownNow();
        }
    }
}

此示例将让您全面了解,当服务器重新启动时,客户端将重新连接。

【讨论】:

    【解决方案3】:

    我没有阅读你所有的代码,但这个对我有用

    别忘了添加 Server 类和发送消息的方法 send...

    客户:

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    
    public class Client {
    static Socket sock=null;
    static DataInputStream in=null;
    static DataOutputStream out=null;
    static boolean connected=false;
    
    static String currentip="";
    static int currentport=0;  
    
    static void refreching(){
    
    try {
        in=new DataInputStream(sock.getInputStream());
        out=new DataOutputStream(sock.getOutputStream());
    
        Thread gg=new Thread() {
            String msg="";
        public void run() {
            while(connected) {
            try {
                msg=in.readUTF();
                System.out.println(msg);
    
            } catch (IOException e) {
               connected=false;
               System.out.println("Reconnecing...");
               while(!connected)
               connect(currentip,currentport);
            }
          }
    
            }
        };
        gg.start();
    }
    catch(Exception e) {
        System.out.println("Problem while reading incoming and outgoing"+    
        "messages!");
        connected=false;
    
                }
    }
    
    static void connect(String iphost, int port){
    try{
    sock=new Socket(iphost,port);
    currentip=iphost;
    currentport=port;
    connected=true;
    refreching();
    System.out.println("Connected!");
    }
    catch(Exception e){
    System.out.println("Cant connect !");
    connected=false;
      }
    }
    
    public static void main(String[] args) {
    connect("127.0.0.1",1234); //Example you can enter another's computer ip 
                              //adress if connected to the same network !!!
    //Send(Message_To_Server); Dont forget to add the sending code!!!
    //Maybe i'll upload a video one day==>how to create a chat application
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-11
      相关资源
      最近更新 更多