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

Posted csj2018

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程相关的知识,希望对你有一定的参考价值。

TCP多线程编程
一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信。
因此服务器端,当我们打开一个Socket以后,通常使用一个无限for循环,在这个for循环内部,每次调用accept方法,返回一个与远程客户新建的Socket连接,紧接着启动一个新的线程,来处理这个连接。

    ServerSocket ss = new ServerSocket(port);
    for( ; ; )
        Socket sock = ss.accept();
        Thread t = new Thread()
            public void run()
                process(sock);
            
        
        t.start();
    

TCPServer.java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

public class TCPServer 
    public static void main(String[] args) throws Exception
        ServerSocket ss = new ServerSocket(9090);
        System.out.println("TCP Server ready");
        for(;;)
            Socket sock = ss.accept();
            System.out.println("Accept from "+sock.getRemoteSocketAddress());
            TimeHandle handle = new TimeHandle(sock);
            handle.start();
        
    

class TimeHandle extends Thread
    Socket sock;
    TimeHandle(Socket sock)
        this.sock = sock;
    
    public void run()
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8)))
            try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8)))
                for(;;)
                    String cmd = reader.readLine();
                    if("q".equals(cmd))
                        writer.write("bye!\\n");
                        writer.flush();
                        break;
                    else if("time".equals(cmd))
                        writer.write(LocalDateTime.now().toString()+"\\n");
                        writer.flush();
                    else
                        writer.write("Sorry?\\n");
                        writer.flush();
                    
                
            
        catch (IOException e)
            e.printStackTrace();
        finally 
            try
                this.sock.close();
            catch (IOException e)
                e.printStackTrace();
            
        
    

运行2次client,服务器端的运行结果
技术图片
TCPClient.java

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TCPClient 
    public static void main(String[] args) throws Exception
        InetAddress addr = InetAddress.getByName("localhost");
        System.out.println(addr);
        try(Socket sock = new Socket(addr,9090))
            try(BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8)))
                try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),StandardCharsets.UTF_8)))
                    writer.write("time\\n");
                    writer.flush();
                    String resp = reader.readLine();
                    System.out.println("Response:"+resp);
                    Thread.sleep(1000);
                    writer.write("q\\n");
                    writer.flush();
                    resp=reader.readLine();
                    System.out.println("Response:"+resp);
                
            
        
    

技术图片

总结:

TCP多线程编程模型:

  • 服务器端使用无限循环
  • 每次accept返回后,创建新的线程来处理客户端请求
  • 每个客户端请求对应一个服务线程
  • 使用线程池可以提高运行效率

以上是关于廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程的主要内容,如果未能解决你的问题,请参考以下文章

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

廖雪峰Java13网络编程-1Socket编程-1网络编程概念

廖雪峰Java13网络编程-3其他-1HTTP编程

廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock

廖雪峰Java11多线程编程-3高级concurrent包-5Atomic

廖雪峰Java2面向对象编程-6Java核心类-3包装类型