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、线程池优化)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程