廖雪峰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编程-2TCP编程
1. Socket 在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据 ...
- 廖雪峰Java13网络编程-1Socket编程-5UDP编程
1. UDP编程: 不需要建立连接 可以直接发送和接收数据 1.1 客户端 DatagramSocket sock = new DatagramSocket(){} sock.connect(addr ...
- 廖雪峰Java13网络编程-1Socket编程-1网络编程概念
1.计算机网络 1.1 什么是计算机网络? 两台或更多计算机组成的网络 同一网络内的任意2台计算机都可以直接通信 所有计算机必须遵循同一种网络协议 1.2 什么是互联网 互联网是网络的网络 互联网采用 ...
- 廖雪峰Java13网络编程-3其他-2RMI远程调用
1.RMI远程调用: Remote Method Invocation 目的:把一个接口方法暴露给远程 示例: 定义一个接口Clock,它有一个方法能够获取当前的时间,并编写一个实现类,来实现这个接口 ...
- 廖雪峰Java13网络编程-3其他-1HTTP编程
1.HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 * 使用浏览器浏览网页和服务器交互使用的就是 ...
- 廖雪峰Java13网络编程-2Email编程-2接收Email
1接收Email协议类型 接收Email:收件人通过MUA软件把邮件从MDA抓取到本地计算机的过程. 1.1 POP3 从MUA到MDA使用最广泛的是协议是POP3 Post Office Proto ...
- 廖雪峰Java13网络编程-2Email编程-1发送email
1.邮件发送 1.1传统邮件发送: 传统的邮件是通过邮局投递,从一个邮局到另一个邮局,最终到达用户的邮箱. 1.2电子邮件发送: 与传统邮件类似,它是从用户电脑的邮件软件(如outlook)发送到邮件 ...
- 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...
- IOS高级编程之三:IOS 多线程编程
多线程的概念在各个操作系统上都会接触到,windows.Linux.mac os等等这些常用的操作系统,都支持多线程的概念. 当然ios中也不例外,但是线程的运行节点可能是我们平常不太注意的. 例如: ...
随机推荐
- CodeForces-1234C-Pipes-dfs
You are given a system of pipes. It consists of two rows, each row consists of nn pipes. The top lef ...
- Android Telephony分析(一) ---- Phone详解
目录: Phone的继承关系与PhoneFactory(GsmCdmaPhone.ImsPhone.SipPhone) Phone进程的启动 Phone对象的初始化(DefaultPhoneNotif ...
- 20130330 printf数组改变 数组指针便利二维数组 二级指针遍历二维数组 ZigZag
1.为什么printf之后数组的值会改变? #include<stdio.h> ; int * Zigzag() { ,j=,limit=; ; ; int a[N][N]; int (* ...
- USACO2008 Patting Heads /// 筛数 oj24705
题目大意: N (1 < N < 100,000)头牛被编号为1-N,围坐成圈 每头牛都被画上数字Ai (1 ≤ Ai ≤ 1,000,000),可能重复 逐个起来拍打 其他身上的数字是 ...
- js原型继承四步曲及原型继承图
一:js原型继承四步曲 //js模拟类的创建以及继承 //动物(Animal),有头这个属性,eat方法 //名字这个属性 //猫有名字属性,继承Animal,抓老鼠方法 //第一步:创建父类 fun ...
- layui中的tab切换
tab切换是常见的效果,为了方便经常使用插架中自带的,下面是layui中自带的tab切换效果, 主要代码如下: <!DOCTYPE html> <html lang="en ...
- Python自学:第五章 使用range( )创建数字列表
# -*- coding: GBK -*- number = list(range(1,6)) print(number) 输出为: [1, 2, 3, 4, 5] 2. # -*- coding: ...
- [JZOJ3235] 数字八
题目 题目大意 给你一个二维的图,其中.代表完好,*代表有缺陷. 现在要在图上刻一个数字\(8\),满足: 由两个矩形组成. 每个矩形中必须有空隙在内部,也就是说,至少为\(3*3\)的矩形. 上矩形 ...
- [JZOJ3339]【NOI2013模拟】wyl8899和法法塔的游戏
题目 题目大意 给你一个数列,每次给出\(r,a,b\),你要找到\(l\in [a,b]\)使得\([l,r-1]\)的异或和最小, 并且要修改\(r\)位置的数. 思考历程 当我看到这题的时候,已 ...
- day14 python02---字符串
day02 数字相关的转换 bin() 2进制oct() 8进制hex() 16进制 字符串 定义:它是一个有序的字符的集合,用于存储和表示基本的文本信息,‘’或“”或‘’‘ ’‘’中间包含的内容称之 ...