当前位置: 首页 > 知识库问答 >
问题:

如何使TCP服务器运行到停止

樊腾
2023-03-14

样品https://github.com/spring-projects/spring-integration-samples/tree/master/basic/tcp-client-server非常适合构建TCP服务器应用程序。它很简单,可以在JVM上运行。它不需要任何应用服务器。

示例使用命令行输入来运行程序。我希望服务器仅从套接字端口而不是通过命令行接受数据。如果删除命令行输入,主线程将完成,程序将不再接受来自端口的输入。我必须始终保持主线程运行。

我在想这样的事情:

    boolean isGatewayStopped = false;
    while (!isGatewayStopped) {
        try {
            Thread.sleep(5000);
            isGatewayStopped = getGatewayStatus();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

我有两个问题:

>

  • 有没有一种干净的方法可以让主线程继续运行?

    如何知道网关已停止?如果用户以“退出”的形式发送TCP数据,则可以停止网关。有没有办法知道网关已停止?

    谢谢

  • 共有2个答案

    韩单弓
    2023-03-14

    您可以从主线程调用网关线程上的etc()以使主线程等待网关线程完成。您需要从网关线程(当它应该停止时)调用通知()来指示它已经完成并且等待线程应该继续运行(在这种情况下,main将运行并退出)。可以在这里找到一个例子。

    或者(一个非常简单的应用程序的不同解决方案),您可以尝试以下方法从主方法读取数据,并在读取的数据等于停止程序的命令时停止程序:

    class Server
    {
       static Executor pool = Executors.newFixedThreadPool(5);
    
       public static void main(String[] args) throws IOException
       {
          ServerSocket serverSocket = new ServerSocket(9000);
          while (true)
          {
             final Socket s = serverSocket.accept();
             Runnable r = new Runnable()
                          {
                             @Override
                             public void run()
                             {
                                // read data from socket 's' here
                                // call System.exit() if command is to stop.
                             }
                          };
             pool.execute(r);
          }
       }
    
    秦宏硕
    2023-03-14

    另一种解决方案是这样的:

    public static void main(String[] args) throws Exception {
            ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
            System.out.println("Hit 'Enter' to terminate");
            System.in.read();
            ctx.close();
    }
    

    您启动Application ationContext并等待控制台输入的停止。

    编辑

    对于要通过应用程序中的事件停止程序的情况,您可以注册ApplicationListener,并在从主界面存在之前等待屏障:

    CountDownLatch exitLatch = new CountDownLatch(1);
    ctx.addApplicationListener(ContextClosedEvent e -> exitLatch.countDown())
    exitLatch.await();
    

    现在,您应该在应用程序中提出一些逻辑来调用ctx。停止()。

     类似资料:
    • 我正试图在我的Android手机和PC之间建立一个TCP套接字连接以进行文件传输。一个TCP服务器程序可以在PC上运行,而TCP客户端程序可以在Android上运行。当服务器程序运行时,一切都很好。但是,当服务器程序不运行时,当客户机试图建立连接时,客户机将挂起(从这个意义上说,它要等待很长时间,直到建立连接)。如何克服这一难题?我想在客户端发现没有这样的服务器运行时立即终止套接字。有可能那样做吗

    • 我是java新手,想知道如何在后台与服务一起运行活动。这样,当活动关闭并重新打开时,它将与服务一起继续。我不知道怎么解释。 假设3个服务,每个服务每小时执行一次。 服务1。。。1小时。。。服务2。。。1小时。。。服务3。已完成。 每次执行时,都会在活动中设置一个文本视图。但是当活动关闭时,不会创建文本视图。 我找到的唯一方法是使用变量,如下例所示 服务1: 服务2: 服务3: 创建活动: 我想知道

    • 问题内容: 我显然正在运行一个实例,因为当我尝试通过输入来启动新服务器时,遇到了以下问题: 我不知道如何停止此服务器并启动新服务器。 在CLI中键入命令时,可以追加任何命令吗? 我的操作系统是Ubuntu 10.04。 问题答案: 连接到节点实例并使用shutdown命令,或者如果您在ubuntu上,则可以尝试通过init.d重新启动Redis服务器: 或停止/启动它: 在Mac上

    • ?> Swoole\Coroutine\Server 是一个完全协程化的类,用于创建协程TCP服务器,支持TCP和unixSocket类型。 与Server模块不同之处: 动态创建销毁,在运行时可以动态监听端口,也可以动态关闭服务器 处理连接的过程是完全同步的,程序可以顺序处理Connect、Receive、Close事件 !> 在4.4以上版本中可用 短命名 可使用Co\Server短名。 方法

    • 程序代码 server.php //创建Server对象,监听 127.0.0.1:9501端口 $serv = new Swoole\Server("127.0.0.1", 9501); //监听连接进入事件 $serv->on('Connect', function ($serv, $fd) { echo "Client: Connect.\n"; }); //监听数据接收事

    • Swoole\Network\Server 使用swoole扩展作为底层驱动 Swoole\Network\SelectTCP 使用PHP提供的stream_select作为事件驱动方式 Swoole\Network\BlockTCP 阻塞方式的TCP Swoole\Network\EventTCP libevent扩展作为底层驱动