Java#36(网络编程)

news2024/11/26 22:42:45

目录

网络通信基本模式

1.Client-Server(CS)​编辑

2.Browser-Server(BS)​编辑

一.网络通信的三要素

1.IP地址: 设备在网络中的地址, 是唯一的标识

2.端口: 应用程序在设备中的唯一的标识

3.协议: 数据在网络中传输的规则, 常见的协议有UDP协议和TCP协议

UDP通信

1.DatagramSocket:发送端和接收端对象

2.DatagramPacket:数据包对象(韭菜盘子)

3.多发多收

TCP通信


 

网络通信基本模式

1.Client-Server(CS)

2.Browser-Server(BS)

一.网络通信的三要素

1.IP地址: 设备网络中的地址, 是唯一的标识

 IP地址形式:
公网地址和私有地址(局域网使用)。
192.168.开头的就是常见的局域网地址,范围即为192.168.0.0--192168.255.255,专门为组织机构内部使用
IP常用命令:
ipconfig: 查看本机IP地址
ping IP地址:检查网络是否连通
特殊IP地址
本机IP: 127.0.0.1或者localhost: 称为回送地址也可称本地回环地址, 只会寻找当前所在本机

lnetAddress 的使用
此类表示Internet协议 (IP) 地址
InetAddress的API
                                                  名称                                        说明
public static InetAddress getLocalHost()             返回本主机的地址对象
public static InetAddress getByName(String host)  得到指定主机的IP地址对象,参数是域名或者IP地址
public String getHostName()                                  获取此IP地址的主机名
public String getHostAddress()                                返回IP地址字符串
public boolean isReachable(int timeout)     在指定毫秒内连通该IP地址对应的主机,连通返回true
代码示范: 

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class ipDemo1 {
    public static void main(String[] args) throws IOException {
        //1.获取本机地址对象
        InetAddress ip1 = InetAddress.getLocalHost();
        //System.out.println(ip1.getHostName());//主机名
        System.out.println(ip1.getHostAddress());//IP地址字符串
        //2.获取域名IP
        InetAddress ip2 = InetAddress.getByName("www.baidu.com");
        System.out.println(ip2.getHostName());
        System.out.println(ip2.getHostAddress());
        //3.获取公网ip对象
        InetAddress ip3 = InetAddress.getByName("14.215.177.38");
        System.out.println(ip3.getHostName());
        System.out.println(ip3.getHostAddress());
        //4.判断是否能通
        System.out.println(ip2.isReachable(3000));//3000代表3000ms,表示在3000ms内是否能通
    }
}

结果展示: 

2.端口: 应用程序设备中的唯一的标识

3.协议: 数据在网络中传输的规则, 常见的协议有UDP协议和TCP协议

UDP通信

UDP协议的特点
UDP是一种无连接、不可靠传输的协议
将数据源IP, 目的地IP和端口以及数据封装成数据包, 大小限制在64KB内, 直接发送出去即可

1.DatagramSocket:发送端和接收端对象

DatagramSocket类构造方法
                构造方法                                                                 说明
public DatagramSocket()               创建发送端的Socket对象,系统会随机分配一个端口号
public DatagramSocket(int port)                创建接收端的socket对象并指定端口号
DatagramSocket类成员方法
                         方法                                                          说明
public void send(DatagramPacket dp)                     发送数据包
public void receive(DatagramPacket p)                   接收数据包

2.DatagramPacket:数据包对象(韭菜盘子)

                构造方法

public DatagramPacket(byte[ ] buf, int length, InetAddress address, int port)       

创建发送端数据包对象

buf:要发送的内容,字节数组  length: 要发送内容的字节长度

address:接收端的IP地址对象  port:接收端的端口号
public DatagramPacket(byte[ ] buf,int length)      

创建接收端的数据包对象

buf:用来存储接收的内容   length: 能够接收内容的长度

代码示范: 第一段代码时客户端代码, 第二段是服务端代码

import java.io.IOException;
import java.net.*;

//客户端
public class ClientDemo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("=====客户端启动=====");
        //1.创建发送端对象
        DatagramSocket socket = new DatagramSocket();
        //2.创建一个数据包对象封装数据
        byte[] by1 = "要发送的数据".getBytes();
        DatagramPacket packet = new DatagramPacket(by1, by1.length, InetAddress.getLocalHost(), 6666);
        //3发送数据出去
        socket.send(packet);
        //关闭
        socket.close();
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

//服务端
public class ServerDemo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("=====服务端启动=====");
        //1.创建接收端对象
        DatagramSocket socket = new DatagramSocket(6666);
        //2.创建接收数据包对象
        byte[] by2 = new byte[1024*64];
        DatagramPacket packet = new DatagramPacket(by2, 0, by2.length);
        //3.等待接收数据
        socket.receive(packet);
        //4.取出数据
        int len = packet.getLength();
        String s1 = new String(by2,0,len);
        System.out.println("收到: "+s1);

        //关闭
        socket.close();
    }
}

结果展示: 运行代码时,要先运行服务端的代码,再运行客户端的代码

3.多发多收

代码示范: 

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

//客户端
public class ClientDemo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("=====客户端启动=====");
        //1.创建发送端对象
        DatagramSocket socket = new DatagramSocket();
        //2.创建一个数据包对象封装数据

        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入: ");
            String str = sc.next();
            if("exit".equals(str)){
                System.out.println("退出");
                socket.close();
                break;
            }
            byte[] by1 = str.getBytes();
            DatagramPacket packet = new DatagramPacket(by1, by1.length, InetAddress.getLocalHost(), 6666);

        //3发送数据出去
        socket.send(packet);
        }
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

//服务端
public class ServerDemo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("=====服务端启动=====");
        //1.创建接收端对象
        DatagramSocket socket = new DatagramSocket(6666);
        //2.创建接收数据包对象
        byte[] by2 = new byte[1024*64];
        DatagramPacket packet = new DatagramPacket(by2, 0, by2.length);
        while (true) {
            //3.等待接收数据
            socket.receive(packet);
            //4.取出数据
            int len = packet.getLength();
            String s1 = new String(by2,0,len);
            System.out.println("收到了来自: "+packet.getAddress()+" 对方的端口是"+packet.getPort()+"的信息: "+s1);
        }

    }
}

结果展示: 

TCP通信

原理图:

Socket
           构造方法                                                                              说明
public Socket(String host ,int port)    创建发送端的Socket对象与服务端连接,参数为服务端程序的ip和端口
        Socket类成员方法                                              说明
OutputStream getOutputStream()                  获得字节输出流对象
InputStream getInputStream()                        获得字节输入流对象

ServerSocket(服务端)
                构造方法                                          说明
public ServerSocket(int port)              注册服务端端口
ServerSocket类成员方法                              说明
public Socket accept()          等待接收客户端的Socket通信连接
连接成功返回Socket对象与客户端建立端到端通信

代码示范: 

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ClientDemo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("====客户端====");
        //1.创建Socket通信管道和请求服务端的连接
        Socket socket = new Socket("127.0.0.1",6666);

        //2.从socket通信段GG中得到一个字符输出流,用来发送数据
        OutputStream os = socket.getOutputStream();

        //3.把第几字节流包装成打印流
        PrintStream ps = new PrintStream(os);

        //4.发送信息
        ps.println("我是发送出来的信息");
        ps.flush();
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo1 {
    public static void main(String[] args) throws IOException {
        System.out.println("====服务端====");
        //1.注册端口
        ServerSocket serverSocket = new ServerSocket(6666);

        //2.必须调用accept方法,的带客户端的连接请求,建立Socket通道
        Socket socket = serverSocket.accept();

        //3.从socket管道中得到一个字节输入流
        InputStream inputStream = socket.getInputStream();

        //4.接收信息
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

        //5.读取信息
        String s1 = br.readLine();
        if(s1 != null){
            System.out.println(socket.getRemoteSocketAddress()+" 发送了: "+s1);
        }
    }
}

结果展示: 

多发多收但只能连接一个客户端

代码示范: 

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo2 {
    public static void main(String[] args) throws IOException {
        System.out.println("====客户端====");
        //1.创建Socket通信管道和请求服务端的连接
        Socket socket = new Socket("127.0.0.1",6666);

        //2.从socket通信段GG中得到一个字符输出流,用来发送数据
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入: ");
            String str = sc.next();
            OutputStream os = socket.getOutputStream();

            //3.把第几字节流包装成打印流
            PrintStream ps = new PrintStream(os);

            //4.发送信息
            ps.println(str);
            ps.flush();
        }

    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo2 {
    public static void main(String[] args) throws IOException {
        System.out.println("====服务端====");
        //1.注册端口
        ServerSocket serverSocket = new ServerSocket(6666);

        //2.必须调用accept方法,的带客户端的连接请求,建立Socket通道
        Socket socket = serverSocket.accept();

        //3.从socket管道中得到一个字节输入流
        InputStream inputStream = socket.getInputStream();

        //4.接收信息
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

        //5.读取信息
        String s1 ;
        while((s1= br.readLine()) != null){
            System.out.println(socket.getRemoteSocketAddress()+" 发送了: "+s1);
        }
    }
}

结果展示: 

多发多收而且能连接多个客户端

代码示范: 第一段是线程类代码, 第二段是客户端代码, 第三段是服务端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ServerSocketThread extends Thread{
    private Socket socket;
    public ServerSocketThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        //3.从socket管道中得到一个字节输入流
        try {
            InputStream inputStream = socket.getInputStream();

            //4.接收信息
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

            //5.读取信息
            String s1 ;
            while((s1= br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + " 发送了: " + s1);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo2 {
    public static void main(String[] args) throws IOException {
        System.out.println("====客户端====");
        //1.创建Socket通信管道和请求服务端的连接
        Socket socket = new Socket("127.0.0.1",6666);

        //2.从socket通信段GG中得到一个字符输出流,用来发送数据
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入: ");
            String str = sc.next();
            OutputStream os = socket.getOutputStream();

            //3.把第几字节流包装成打印流
            PrintStream ps = new PrintStream(os);

            //4.发送信息
            ps.println(str);
            ps.flush();
        }

    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo2 {
    public static void main(String[] args) throws IOException {
        System.out.println("====服务端====");
        //1.注册端口
        ServerSocket serverSocket = new ServerSocket(6666);

        //定义一个死循环不断接收客户端的Socket管道
        while (true) {
            //把接收到的客户端Socket管道,交给一个独立的子线程
            Socket socket = serverSocket.accept();
            //创建独立线程处理socket
            new ServerSocketThread(socket).start();

        }
    }
}

结果展示: 

用线程池进行优化

代码示范: 

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ServerReaderRunnable implements Runnable{
    private Socket socket;
    public ServerReaderRunnable(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        //3.从socket管道中得到一个字节输入流
        try {
            InputStream inputStream = socket.getInputStream();

            //4.接收信息
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

            //5.读取信息
            String s1 ;
            while((s1= br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + " 发送了: " + s1);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo3 {
    public static void main(String[] args) throws IOException {
        System.out.println("====客户端====");
        //1.创建Socket通信管道和请求服务端的连接
        Socket socket = new Socket("127.0.0.1",6666);

        //2.从socket通信段GG中得到一个字符输出流,用来发送数据
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入: ");
            String str = sc.next();
            OutputStream os = socket.getOutputStream();

            //3.把第几字节流包装成打印流
            PrintStream ps = new PrintStream(os);

            //4.发送信息
            ps.println(str);
            ps.flush();
        }

    }
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

public class ServerDemo3 {
    private static ExecutorService pool = new ThreadPoolExecutor(
            3,6,5,
            TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),
            Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
    public static void main(String[] args) throws IOException {
        System.out.println("====服务端====");
        //1.注册端口
        ServerSocket serverSocket = new ServerSocket(6666);

        //定义一个死循环不断接收客户端的Socket管道
        while (true) {
            Socket socket = serverSocket.accept();
            ServerReaderRunnable srr = new ServerReaderRunnable(socket);
            pool.execute(srr);

        }
    }

结果展示: 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/83659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java在线影院系统xxdto

毕业设计也不需要做多高端的程序&#xff0c;毕业设计对于大多数同学来说&#xff0c;为什么感觉到难&#xff0c;最重要的一个原因&#xff0c;那就是理论课到实践课的转变&#xff0c;很多人一下不适应&#xff0c;本能开始拒绝&#xff0c;如果是一个考试&#xff0c;大家都…

接口功能测试经验及策略总结,希望可以帮到你

目录 前言 一、接口测试范围 二、接口测试策略 接口设计检查 接口依赖关系检查 接口输入/输出验证 密码重置接口 用户经验值查询接口 比赛成绩同步接口 三、总结 四、重点&#xff1a;配套学习资料和视频教学 前言 由于平台服务器是通过接口来与客户端交互数据提供…

CH9434 嵌入式Linux与安卓系统驱动移植和使用教程

1 前言 CH9434是一款SPI转四串口转接芯片&#xff0c;提供四组全双工的9线异步串口&#xff0c;用于单片机/嵌入式/安卓系统扩展异步串口。提供25路GPIO&#xff0c;以及支持RS485收发控制引脚TNOW。本篇基于STM32MP157处理器平台&#xff0c;介绍CH9434在嵌入式Linux系统/安卓…

Linux学习-85-memcache、Docker安装和配置(自启动)过程

17.14 memcache安装和配置&#xff08;自启动&#xff09;过程 memcache 是一个高性能的分布式的内存对象缓存系统&#xff0c;通过在内存中维护一张统一的、巨大的 Hash 表&#xff0c;它能够用来存储各种格式的数据&#xff0c;包括图像、视频、文件及数据库检索的结果等。简…

【LeetCode】1781. 所有子字符串美丽值之和

题目描述 一个字符串的 美丽值 定义为&#xff1a;出现频率最高字符与出现频率最低字符的出现次数之差。 比方说&#xff0c;“abaacc” 的美丽值为 3 - 1 2 。 给你一个字符串 s &#xff0c;请你返回它所有子字符串的 美丽值 之和。 示例 1&#xff1a; 输入&#xff1a;s …

R语言对二分连续变量进行逻辑回归数据分析

教育或医学的标准情况是我们有一项连续的措施&#xff0c;但随后我们对那些具有临床/实践意义的措施有了切入点。一个例子是BMI。 相关视频&#xff1a;R语言逻辑回归&#xff08;Logistic回归&#xff09;模型分类预测病人冠心病风险 逻辑回归Logistic模型原理和R语言分类预测…

springcloud04:Feign使用接口方式调用服务以及Hystrix服务熔断

Feign使用接口方式调用服务以及Hystrix服务熔断Feign负载均衡客户端集成FeignHystrixHystrix定义服务熔断服务端集成Hystrix(springcloud-provider-dept-hystrix)实现服务熔断客户端集成Hystrix实现服务降级服务监控Feign负载均衡 简介 客户端集成Feign pom文件 <!--Feig…

golang编译tag学习

官方资料 官方解释&#xff1a; https://pkg.go.dev/cmd/go#hdr-Build_constraints ,go help buildconstraint 也能看到描述 根据官方描述&#xff0c;go1.16开始建议使用go:build方式&#xff0c;与build相比更容易被人阅读。 有关go:build注释的解析&#xff1a; src/go/buil…

[附源码]Node.js计算机毕业设计道岔故障监测系统设计Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

CSS -- 05. CSS定位方式总结

文章目录CSS定位1 定位1.1 为什么需要定位1.2 定位组成1.3 静态定位 static&#xff08;了解&#xff09;1.4 相对定位 relative&#xff08;重要&#xff09;1.5 绝对定位 absolute&#xff08;重要&#xff09;1.6 子绝父相1.7 固定定位 fixed&#xff08;重要&#xff09;1.…

SpringMVC(三) 获取请求参数(干货、超详细)

1.环境搭建 见SpringMVC(一) 2.获取参数 2.1使用Servlet API获取请求参数 将HttpServletRequest作为控制器方法的形参&#xff0c;DispatcherServlet发现控制器方法有HttpServletRequest形参&#xff0c;就把参数给传进来&#xff0c;HttpServletRequest就是javaWeb中的Htt…

[附源码]计算机毕业设计房屋租赁信息系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

Python文件操作详解(一)

今天继续给大家介绍Python相关知识&#xff0c;本文主要内容是Python文件操作详解。 一、Python文件处理简介 使用Python可以编写程序处理文件&#xff0c;Python可以处理的文件值得是任何存储在辅助存储器上的数据序列。 在Python中&#xff0c;对于文件的处理通常由一定的流…

Code::Blocks(V20.03)工具安装、汉化、使用一条龙介绍

文章目录1、猿如意介绍2、Code::Blocks简介3、Code::Blocks安装3.1 下载3.2 安装3.3 汉化&#xff08;可选项&#xff09;4、Code::Blocks使用4.1 基本界面一览4.2 单个小工程5、Code::Blocks使用感受1、猿如意介绍 猿如意官网客户端下载地址 正如官网页面介绍猿如意的功能和作…

Allegro如何创建Group操作指导

Allegro如何创建Group操作指导 Allegro支持把器件,过孔和走线等等做成一个Group,对于PCB设计也很大帮助,如何创建一个group,具体操作如下 以下面图片为例 选择edit-groups Options选项里输出任意一个Group的名字 之后会出现一个Create Group弹窗,选择是 之后find选择…

年终将近,如何快速处理销售数据分析

编者按&#xff1a;如何做好企业销售数据分析&#xff0c;基于低代码平台实现的智能销售系统&#xff0c;以四大数据引擎为支撑&#xff0c;助力企业数据管理。 关键词&#xff1a;低代码平台&#xff0c;企业域管理&#xff0c;数据视图&#xff0c;智能报表&#xff0c;数据…

FFmpeg音视频编解码详解

本文你可以了解到 如何在 NDK 层调用 OpenGL ES &#xff0c;以及使用 OpenGL ES 来渲染 FFmpeg 解码出来的视频数据。 一、渲染流程介绍 在 Java 层&#xff0c;Android 已经为我们提供了 GLSurfaceView 用于 OpenGL ES 的渲染&#xff0c;我们不必关心 OpenGL ES 中关于 EGL…

开发游戏相关业务该如何选择云服务器及相关产品?

游戏开发分为两种&#xff0c;第一种就是角色扮演类&#xff0c;另一种就是休闲类游戏&#xff0c;角色扮演类游戏对于计算能力以及游戏安全有很大的尤其&#xff1b;而休闲类游戏对于资源、运维、成本控制有所要求&#xff0c;下面就给大家展示一下腾讯云官方给出的解决方案&a…

如何去做一个完整的网站 SEO 优化方案?

想要做好网站优化&#xff0c;就必须制定一套适合自己的网站优化方案。优化只是一个过程&#xff0c;更多的是简单工作的重复&#xff0c;但也有技巧和方法。这个时候&#xff0c;你的网站优化方案就显得尤为重要。为您指明今后优化工作的途径&#xff0c;您在上一篇文章《传:东…

网络小白入门之路之以太网链路聚合 ---尚文网络奎哥

随着业务的发展和园区网络规模的不断扩大&#xff0c;用户对于网络的带宽、可靠性要求越来越高。传统解决方案通过升级设备方式提高网络带宽&#xff0c;同时通过部署冗余链路并辅以STP&#xff08;Spanning Tree Protocol&#xff0c;生成树协议&#xff09;协议实现高可靠。传…