javaEE(网络编程、TCP、线程池优化)
网络编程
- Client-Server(CS)
- Browser/Server(BS)
1.客户端--服务端
安装客户端
- 更新。
- 依赖PC
2.浏览器和服务端
- 分布式
- 兼容性
- 一站开发
网络通信:
- UDP 不确定在线 不做消息确认
- TCP可靠的通信
- 及时通信
- 模拟BS通信
三要素
- IP地址:设备在网络中的地址,唯一标识
- 端口:应用程序在设备中的唯一标识
- 协议:数据在网络中的传输规则,常见的有UDP协议和TCP协议
IPv4:
- 32位(4字节)
- 点分十进制
IPv6:
- 128位(16个字节),号称可以为地球上的每一粒沙子编号
- 冒分十六进制
域名
- 公网地址、私网地址(局域网使用)
- 192.168..开头就是局域网 192.168.0.0--192.168.255.255,专门内部使用
Ip命令:
- ipcofig:查看本机ip
- ping IP的地址:检查网络是否连通
特殊id:
- 127.0.0.1或者localhost:只会找本机
Ip地址操作类
InetAddress
- public static InetAddress getLocalHost() 返回主机的ip
- public static InetAddress getByName()得到指定的主机ip地址对象,参数是域名或者ip地址
- public String getHostName()获取此ip地址的主机名
- public String getHostAddress()返回ip地址的主机名
- public boolean isReachable(int timeout)在毫秒内连通该ip地址对应的主机,连通返回true
main(){
//1.获得本机ip对象
InetAddress ip = InetAddress .getLocalHost();
//得到域名
InetAddress ip = InetAddress .getByName("www.baidu.com");
//公网的ip
InetAddress ip = InetAddress .getByName("112.82.248.76");
端口
标识在计算机上运行的程序,规定的是一个16的二进制,0-65535.
端口类型:
- 周至端口:0-1023(HTTP:80,FTP:21)
- 注册端口:1024-49151(Tomcat:8080,MySQL:3306)
- 动态端口:49152-65535
协议
连接和通讯数据的规则--------网络通讯协议
- OSI参考模型:世界互联网协议规范
- TCP/IP参考模型:事实的国际标准
TCP:
- 应用层
- HTTP\FTP\DNS\SMTP
- 传输层
- TCP\UDP
- 网路层
- IP\ICMP
- 数据链路层+物理
- 物理寻址、比较流
传输层的协议:
- TCP:传输控制协议
- UCP:用户数据报协议
TCP:
- 采用TCP协议,必须双方先建立连接,它使面向连接的可靠通信协议
- 传输前,采用三次握手方式建立连接,所以是可靠的
- 在连接中可以进行大数据量的传输
- 连接、发送数据都需要确认、且传输完毕后、还要释放已建立的连接。通信效率较低
TCP协议的场景:
- 对信息安全要求较高的场景,文件下载,金融数据通信
TCP的三次握手
- 客户端向服务器发送请求--等待服务器确认
- 服务器向客户端返回了一个相应--告诉客户端接受到了请求
- 客户端向服务器再次发出确认信息---连接建立
TCP的四次挥手
- 客户端向服务器发出取消请求
- 服务器向客户端返回一个相应---表示收到客户端取消请求
- 服务器向客户端发出确认消息
- 客户端再次发出消息--连接取消
UDP:
- 一中无连接、不可靠的传输协议
- 将数据源ip、目的地ip、和端口封装成数据包、不需要建立连接
- 每个数据包的大小限制在64kb内
- 发送不管对方是否准备好,接收方也不确认,所以是不可靠的
- 可以发送广播、发送数据结束时无需释放资源、开销小、速度快
适合语音通话、视频会话
UDP
数据包:
构造器:
- public DatagramPacket(byte[] buf,int length, InetAddress,int port)port接受的端口
- public DatagramPacket(byte[] buf,int length) 创建接受端的数据包 buf储存的内容 length 能接受的长度
DatagramSocket发送端和接收端对象
构造器:
- public DatagramSocket()
- public DatagramSocket(int port)
方法:
- public void send( DatagramPacket dp) 发送数据包
- public void receive( DatagramPacket p)接收数据包
main(){
DatagramSocket sock =new DatagramSocket();
//数据包
byte[] buffer ="我是韭菜".getBytes();
DatagramPacket packet =new DatagramPacket(buffer,buffer.length,InetAddress.getLocalHost(),8888);
sock.send(packet);
sock.close();
}
main(){
DatagramSocket sock =new DatagramSocket(8888);
//数据包
byte[] buffer =new byte[1024*64];
DatagramPacket packet =new DatagramPacket(buffer,buffer.length);
sock.receive(packet);
String s =new String(buffer);
socket.close();
}
多发多收
以后吧累了
TCP
面向连接,安全,可靠
java.net.Socket
Socket:
- public Socket(String host,int port) 创建Socket对象与服务器连接,参数为服务器的ip和端口
方法:
- OutputStream getOutputStream()获得字节输出流
- InputStream getInputStream() 获得字节输入流
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
//发送消息
ps.print("约么");
ps.flush();
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
Socket socket =ss.accept();
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms)
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
多发多收
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
Socket socket =ss.accept();
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
但是服务daunt不可以接受多个客户端信息。
多客户端
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
//收消息
while(ms=br.readLine()!=null){
Socket socket =ss.accept();
new SerberThread(socket).start();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
线程:
public class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
}
线程池优化
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
//定义线程池
private Static ExecutorService pool =new ThreadPoolExecutor(3,5,6,TimeUnit.SECONDS,new ArrayBlockingQueue(2,Executor.defaultThreadFactorty(),new ThreadPoolExcutor.AbortPolicy()));
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
//收消息
while(ms=br.readLine()!=null){
Socket socket =ss.accept();
Runner a =new SerberThread(socket);
pool.excute(a);
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
线程:
public class ServerThread implement Runnable{
private Socket socket;
public ServerThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
}
优点:
- 适合通信时长较短的案例
即时通讯
- 客户端
main(){
try{
//创建Socket管道建立连接
Socket socket =new Socket("127.0..0..1",7777);
//创建一个读线程
new ClienThread(socket).start();
//得到字节输出流
getOutputStream is =socket.getOutputStream();
//变成高级流
PrintStream ps =new PrintStream(is);
Scanner sc =new Scanner(System.in);
//发送消息
while(true){
System.out.print("请说");
String ms = sc.nextLine();
ps.println(ms);
ps.flush();
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
客户端的线程
public class ClienrThread implement Runnable{
private Socket socket;
public ClienThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
String line;
while(line=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+line);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
}
ServerSocket(服务端)
- public ServerSocket(int port) 注册服务端
//定义线程池
private Static ExecutorService pool =new ThreadPoolExecutor(3,5,6,TimeUnit.SECONDS,new ArrayBlockingQueue(2,Executor.defaultThreadFactorty(),new ThreadPoolExcutor.AbortPolicy()));
//客户端的留言
public static List<Socket> allSocket = new ArrayList<>();
main(){
try{
//创建ServerSocket管道建立连接
ServerSocket ss =new ServerSocket(7777);
//收消息
while(ms=br.readLine()!=null){
Socket socket =ss.accept();
allStock.add(socket);
Runner a =new SerberThread(socket);
pool.excute(a);
}
//socket.close();不建议关闭流
}catch(Exception e){
e.printStackTrace();
}
}
线程:
public class ServerThread implement Runnable{
private Socket socket;
public ServerThread(Socket socket){
this.socket-socket;
}
@Override
public void run(){
try{
//得到字节输出流
getInputStream is =socket.getInputStream();
//变成高级流
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//收消息
while(ms=br.readLine()!=null){
System.out.print(socket.RemoteSocketAddress()+"说了"+ms);
sendMssageToAll(line);
}
//socket.close();不建议关闭流
}catch{
e.printStrackTrace();
}
}
private void sendMssageToAll(String msg){
for(Socket socket:ServlerThread.allSocket){
PrintStream ps =new PrintStream(socket.getOutputStream());
ps.println(msg);
ps.flush();
}
}
}
javaEE(网络编程、TCP、线程池优化)的更多相关文章
- java笔记--使用线程池优化多线程编程
使用线程池优化多线程编程 认识线程池 在Java中,所有的对象都是需要通过new操作符来创建的,如果创建大量短生命周期的对象,将会使得整个程序的性能非常的低下.这种时候就需要用到了池的技术,比如数据库 ...
- Socket网络编程(TCP/IP/端口/类)和实例
Socket网络编程(TCP/IP/端口/类)和实例 原文:C# Socket网络编程精华篇 转自:微冷的雨 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次 ...
- 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法
网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...
- Socket网络编程-TCP编程
Socket网络编程-TCP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.socket介绍 1>.TCP/IP协议 2>.跨网络的主机间通讯 在建立通信连接的 ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- GO语言练习:网络编程 TCP 示例
1.代码 2.编译及运行 1.网络编程 TCP 示例 simplehttp.go 代码 package main import ( "net" "os" &qu ...
- 并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- Mysql线程池优化笔记
Mysql线程池优化我是总结了一个站长的3篇文章了,这里我整理到一起来本文章就分为三个优化段了,下面一起来看看. Mysql线程池系列一(Thread pool FAQ) 首先介绍什么是mys ...
- 网络编程TCP协议-聊天室
网络编程TCP协议-聊天室(客户端与服务端的交互); <span style="font-size:18px;">1.客户端发数据到服务端.</span> ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
随机推荐
- halcon如何识别硬币?
halcon如何识别硬币? 前言 最近一直在学习halcon,在此做了一个案例,分享给大家,效果图如下: 1.思路分析 通过观察,发现1元,5角,1角,它们在面值的文字描述不一样,硬币显示的花纹不一样 ...
- Springcoud-netflix 笔记
SpringCloud_Netflix 微服务一代(Netflix)学习前提: JAVASE. 数据库(MySQL). 前端(HTML+CSS+JavaScript||JQuery.Bootstrap ...
- day32 6 请求转发与重定向的区别、session会话对象 & cookie & 8 应用程序上下文对象ServletContext & 5 请求转发与jsp页面内置对象
1 请求转发与重定向的区别 2 session与cookie的区别 3 过滤器与监听器的区别 4 web-inf目录 web-inf目录是安全目录,无法从客户端访问,只能通过(服务端的)servlet ...
- 5V升压12.6V
产品概述 PW4053 是一款 5V 输入,最大 1.2A 充电电流,支持三节锂离子电池的升压充电管理 IC.PW4053 集成功率 MOS,采用异步开关架构,使其在应用时仅需极少的外围器件,可有效减 ...
- Python requests 上传文件(以上传图片为例)
from requests_toolbelt import MultipartEncoderimport requests encoderl = MultipartEncoder( fields = ...
- WinUI(WASDK)使用MediaPipe检查手部关键点并通过ML.NET进行手势分类
前言 之所以会搞这个手势识别分类,其实是为了满足之前群友提的需求,就是针对稚晖君的ElectronBot机器人的上位机软件的功能丰富,因为本来擅长的技术栈都是.NET,也刚好试试全能的.NET是不是真 ...
- 【Redis场景1】用户登录注册
细节回顾: 关于cookie和session不熟悉的朋友: 建议阅读该博客:https://www.cnblogs.com/ityouknow/p/10856177.html 执行流程: 在单体模式下 ...
- 回溯法求解n皇后问题(复习)
回溯法 回溯法是最常用的解题方法,有"通用的解题法"之称.当要解决的问题有若干可行解时,则可以在包含问题所有解的空间树中,按深度优先的策略,从根节点出发搜索解空间树.算法搜索至解空 ...
- 【转载】SQL SERVER 将多行数据合并成一行
昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行 比如表中有两列数据 : ep_classes ep_name A ...
- Kali Win-KeX Win
内容: 概述 用法 开始 启动根会话 会话管理 声音支持 多屏支持 停止 概述 窗口模式下的 Win-KeX 将在单独的窗口中运行 Kali Linux 桌面会话. 窗口模式有助于在视觉上将 Wind ...