多线程 Java TCP 客户端

Posted

技术标签:

【中文标题】多线程 Java TCP 客户端【英文标题】:Multi-threaded Java TCP Client 【发布时间】:2015-01-26 10:09:14 【问题描述】:

我正在编写一个 Java 客户端应用程序(带有 TCP/IP 的基本 Java Net 包)。客户端必须从 system.in 获取输入,同时必须通过套接字输入流监听来自服务器的任何消息。 一旦收到来自 system.in 的输入,客户端将获取该输入,进行一些处理并将其作为请求发送到服务器。 所以基本上2个进程运行,

-监听客户端请求

- 监听服务器响应。

我为此实现了 2 个线程并在主线程中运行消息处理。 这样的设计够好吗?

有没有办法将从 system.in 收到的消息返回到主线程。线程 run() 方法返回 void。我使用了一个 volatile 变量来返回接收到的字符串,但它说 volatile 非常昂贵,因为它不使用 cpu 缓存来存储变量。

【问题讨论】:

为什么?您只需要在发送请求后获取响应。你不需要两个线程。 服务器需要在连接时发送一些定义,所以客户端必须在监听的同时还必须监听来自system.in的请求。跨度> 【参考方案1】:

您可以查看我为 Java 套接字和多线程示例编写的这两个项目。

Client Server

我猜 ClientExample 是您要搜索的,但您也可以查看服务器部分。

基本上这个想法是启动两个单独的线程来监听不同的输入 - 套接字和控制台。

final Thread outThread = new Thread() 
    @Override
    public void run() 
        System.out.println("Started...");
        PrintWriter out = null;
        Scanner sysIn = new Scanner(System.in);
        try 
            out = new PrintWriter(socket.getOutputStream());
            out.println(name);
            out.flush();

            while (sysIn.hasNext() && !isFinished.get()) 
                String line = sysIn.nextLine();
                if ("exit".equals(line)) 
                    synchronized (isFinished) 
                        isFinished.set(true);
                    
                
                out.println(line);
                out.flush();
                disconnect();
            
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
         finally 
            if (out != null) 
                out.close();
            
        
    ;
;
outThread.start();

另一个用于套接字输入的线程:

        final Thread inThread = new Thread() 
            @Override
            public void run() 
                // Use a Scanner to read from the remote server

                Scanner in = null;
                try 
                    in = new Scanner(socket.getInputStream());
                    String line = in.nextLine();
                    while (!isFinished.get()) 
                        System.out.println(line);
                        line = in.nextLine();
                    
                 catch (Exception e) 
//                  e.printStackTrace();
                 finally 
                    if (in != null) 
                        in.close();
                    
                
            ;
        ;
        inThread.start();

希望对你有帮助:)

【讨论】:

这很有帮助!但是我必须先将控制台输入传递给主线程,然后再将其写入套接字。有没有办法将 sysIn 返回到主线程? 是否需要在主线程中处理输入?不能在后台线程调用处理方法吗? 谢谢建议,但是如果线程的处理需要时间。使用多个线程是没有用的,对吧?该线程将在处理 system.in 时被阻塞。 如果处理需要时间,您必须生成一个新线程(或使用ThreadPool)来处理数据然后发送。所以它会是这样的:主线程产生两个从系统输入和套接字读取的新线程。读取系统输入的线程为每个将处理它的新数据生成一个新线程。处理完成后,该线程负责将其发送到服务器。另一种方法是使用一个队列来保存处理过的数据,另一个线程读取队列并将数据发送到服务器。 这变得更加复杂。我建议您将所有这些内容拆分为单独的问题。

以上是关于多线程 Java TCP 客户端的主要内容,如果未能解决你的问题,请参考以下文章

java socket多线程问题,我写了一个socket tcp服务端,高手来进来看下,谢啦。是关于多客户端并联的问题

Java Socket实现基于TCP和UDP多线程通信

廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

linux C语言 TCP 多线程 简易聊天室

具有多线程服务器 (TCP/IP) 的客户端/服务器聊天室

Socket 多线程编程