javaEE(网络编程、TCP、线程池优化)
2022/6/24 14:20:37
本文主要是介绍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、线程池优化)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略