【问题标题】:Java socket program for client and server communication auto reconnect用于客户端和服务器通信自动重新连接的 Java 套接字程序
【发布时间】:2023-03-23 23:49:01
【问题描述】:

我想开发客户端和服务器通信,我已经为客户端和服务器编写了一些代码,但是一旦客户端和服务器连接,就不需要一次又一次地重新连接。但是,在我当前的代码中,它们会一次又一次地重新连接。

  1. InetAddress host = InetAddress.getLocalHost();
  2. Socket s = new Socket(host.getHostName(), 4321);

第二行每次都会创建新的连接,这就是我要解决的问题(他们只需要连接一次)。

ClientClass.java

public class CientClass {

public static void main(String[] args)  
  {
    System.out.println("CLIENT SITE");
    while (true) {
        try {
            InetAddress host = InetAddress.getLocalHost();
            Socket s = new Socket(host.getHostName(), 4321);
            DataOutputStream dout = new DataOutputStream(s.getOutputStream());
            Scanner sc = new Scanner(System.in);
            System.out.println("Ener for server:");
            String data = sc.next();
            dout.writeUTF(data);
        }
        catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
    }
  }
}

Serverclass.java

public class Serverclass {

public static void main(String[] args) {
    System.out.println("SERVER SITE");
    while (true) {
        try {
            ServerSocket ss = new ServerSocket(4321);
            Socket s = ss.accept();
            DataInputStream din = new DataInputStream(s.getInputStream());
            String str = (String) din.readUTF();
            System.out.println("message:" + str);
            ss.close();
        }
        catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
    }
  }
}

clientClass 从控制台读取命令并发送到服务器,但它不应在初始连接后继续重新连接。

在重启服务器的情况下,客户端应该自动连接,并且客户端应该能够向服务器发送命令。

我想我不需要更改服务器类代码。只需要更改clientClass代码。怎么样?

【问题讨论】:

  • 您能重新表述一下您的问题吗?目前还不清楚你想做什么。你的代码也有点奇怪。为什么要创建包装在while(true) 循环中的客户端/服务器?这似乎没有意义。不要谈论你的套接字丢失的关闭......
  • 是的,请再看一遍..
  • 看看 L.Spillner 的回答,它回答得很好,甚至解释得很好?

标签: java sockets


【解决方案1】:

好的,有两个主要原因会始终建立新连接。

首先,对于 ServerClass 中 while(true) 循环的每个循环,您正在创建一个新的服务器套接字并通过调用 ServerSocket.accept() 等待新连接,这也是一个阻塞操作,这意味着服务器会一直阻塞直到新连接到达。

这种行为的第二个原因是,您总是通过创建新套接字来强制从 ClientClass 建立新连接。 套接字建立端到端的连接。创建并连接后,您无需再创建一个。

对您来说最方便的解决方法是替换 while(true) 循环,使其仅以某种方式涵盖真正的发送/接收逻辑:

客户端类

  try
  {
    InetAddress host = InetAddress.getLocalHost();
    Socket s = new Socket( host.getHostName(), 4321 );
    DataOutputStream dout = new DataOutputStream( s.getOutputStream() );
    while ( isAlive )
    {
      Scanner sc = new Scanner( System.in );
      System.out.println( "Ener for server:" );
      String data = sc.next();
      dout.writeUTF( data );
    }
  }
  catch ( Exception e )
  {
    System.out.println( e );
    e.printStackTrace();
  }

服务器类

try
      {
        ServerSocket ss = new ServerSocket( 4321 );
        Socket s = ss.accept();
        DataInputStream din = new DataInputStream( s.getInputStream() );
        while ( isAlive )
        {
          String str = (String) din.readUTF();
          System.out.println( "message:" + str );
        }
        ss.close();
      }
      catch ( Exception e )
      {
        System.out.println( e );
        e.printStackTrace();
      }

【讨论】:

  • 如果我在写 1) InetAddress host = InetAddress.getLocalHost(); 2) 套接字 s = new Socket(host.getHostName(), 4321);或(服务器端) 3)ServerSocket ss = new ServerSocket( 4321 ); 4) 套接字 s = ss.accept();如果我重新启动服务器,则在循环之外它无法再次重新连接。
  • @BimalKumarDalei 你说得对。处理此类问题包括检查连接是否已断开,并且仅当它具有 ServerSocket ss 时才必须发出新的 ss.accept() 调用。在您的实现中,您不断创建新的 ServerSocket。如果你真的想要一个可以接受多个连接并且能够让设备重新连接的服务器服务,你应该看看线程化你的应用程序。 Javadocs 中的 ExecutorService 示例展示了一个很好的示例。
  • @BimalKumarDalei 除了我上面的评论之外,您还应该阅读blog post 关于“半开”TCP 连接的内容。它详细描述了您的问题,甚至提供了一些如何处理这些问题的示例。具体实现由你决定。如果您在这样做时遇到更多问题,请随时编辑您的帖子并发表评论,以便我再看一遍。最好的问候。
猜你喜欢
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多