廖雪峰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返回后,创建新的线程来处理客户端请求
  • 每个客户端请求对应一个服务线程
  • 使用线程池可以提高运行效率

原文地址:https://www.cnblogs.com/csj2018/p/11145986.html

时间: 2024-11-05 04:00:41

廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程的相关文章

廖雪峰Java13网络编程-1Socket编程-2TCP编程

在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络. Socket/TCP/部分IP都是由操作系统提供的.不同的编程语言只是提供了对操作系统调用的加单的封装,例如Java提供的几个Socket相关的类就封装了操作系统提供的接口. 为什么需要Socket? 因为仅仅通过IP地址进行通信还不够,同一台计算机同一时间会运行多个网络程序.当计算机收到一个数据包的时候

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

1.什么是计算机网络? 两台或更多计算机组成的网络 同一网络内的任意2台计算机都可以直接通信 所有计算机必须遵循同一种网络协议 什么是互联网 互联网是网络的网络 互联网采用TCP/IP协议 * TCP/IP协议泛指互联网协议 * 其中最重要的2个协议是TCP协议和IP协议 IP地址用于唯一标识一个网络接口(Network Interface) IPv4采用32位地址,类似101.202.99.12 IPv6采用128位地址,类似2001:0DA8:100A:0000:0000:1020:F2F3

廖雪峰Java13网络编程-1Socket编程-5UDP编程

传统邮件发送: 传统的邮件是通过邮局投递,从一个邮局到另一个邮局,最终到达用户的邮箱. 电子邮件发送: 与传统邮件类似,它是从用户电脑的邮件软件(如outlook)发送到邮件服务器上,然后经过若干个邮件服务器的中转,到达对方邮件服务器上,收件方就可以用软件或浏览器来接收邮件. MUA(邮件软件,Mail User Agent)-->MTA(邮件服务器,Mail Transfer Agent)-->MTA-->MDA(邮件投递代理,Mail Delivery Agent)<--MUA

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

HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 使用浏览器浏览网页和服务器交互使用的就是HTTP协议 手机应用上绝大多数程序与服务器之间交互数据使用的也是HTTP协议. HTTP是一个请求/响应协议.浏览器发送一个请求,服务器收到以后,然后发送响应. HTTP 1.0特点: 每次请求都会创建一个新的HTTP连接,浏览器在请求一个网页之后,往往还是多次请求图片.CSS.JS等其他资源,而创建 原

【C++编程】C++实现多线程编程

在C++的多线程编程实现里有两种方式,一种是Windows头文件里的CreateProcess,另一种是process.h里的_beginthread,我这里用的是后一种,并且将多线程操作封装成了类似Java里的Thread类. Thread类包含四种操作(对应线程的几种状态):就绪(start),挂起(suspend).恢复(resume)以及终止(terminate),另外,还包含了一个可以设置线程超时的操作. Thread类代码如下(Thread.h): #ifndef THREAD_H

5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结

5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task 5天玩转C#并行和多线程编程 —— 第四天 Task进阶  一.多线程带来的问题 1.死锁问题  前面我们学习了Task的使用方法,其中Task的等待机制让我们瞬间爱上了它,但是如果我们在调用Task.WaitAll方法等待所有线程时,如果有一个Task一直不返

廖雪峰Java1-3流程控制-3条件判断

1.if条件判断的格式 if (条件) { 代码块 } if (条件) { 代码块1 } else { 代码块2 } if (条件1) { 代码块1 } else if { 代码块2 } else { 代码块3 } 2.整型判断 条件判断注意的事项: 注意判断顺序 注意边界条件 int n = 100; if (n >= 90){ System.out.println("优秀"); }else if(n >= 60){ System.out.println("及格

廖雪峰Java1-3流程控制-6 do-while循环

do-while循环 do-while先执行循环,再判断条件. 条件满足时继续循环:条件不满足时退出:至少循环1次 int sum =0; int n = 1; do{ sum = sum + n; n++; }while (n<10); System.out.println(n); System.out.println(sum); 原文地址:https://www.cnblogs.com/csj2018/p/10252721.html

廖雪峰Java1-3流程控制-5循环

while循环 while循环首先判断条件: 条件满足时循环:条件不满足时退出循环 如果一开始条件就不满足,一次都不循环.如while false int sum = 0; int n = 1; while (n < 10){ sum = sum + n; n++; } System.out.println(n); System.out.println(sum); 避免死循环 当循环条件永远循环时,进入死循环.死循环导致CPU 100%占用,要避免死循环 int sum = 0; int n =