Java_网络编程

网络通信的关键三要素

IP、端口号、协议

IP地址

IP地址(Internet Protocol):全程“互联网协议地址”,是分配给上网设备的唯一标志。

IP地址有两种形式:IPv4、IPv6

在这里插入图片描述

在这里插入图片描述

InetAddress

代表IP地址

InetAddress 的常用方法如下

名称说明
public static InetAdress getLocalHost()获取本机IP,会以一个inetAddress 的对象返回
public static InetAddress getByName(String host)根据ip地址或者域名,返回一个inetAddress对象
public String getHostName()获取该IP地址对象对应的主机名。
public String getHostAddress()获取该IP地址对象中的ip地址信息
public boolean isReachable(int timeout)在指定毫秒内,判断主机与该ip对应主机是否能够联通
import java.net.InetAddress;
import java.sql.SQLOutput;

public class InetAddresstest {


    public static void main (String[] args )throws Exception
    {
        //1、获取本机IP地址对象

        InetAddress ip1 = InetAddress.getLocalHost();
        System.out.println(ip1.getHostName());
        System.out.println(ip1.getHostAddress());

        //2、获取指定IP或者域名的IP地址对象
        InetAddress ip2=InetAddress.getByName("www.baidu.com");
        System.out.println(ip2.getHostName());
        System.out.println(ip2.getHostAddress());

        System.out.println(ip2.isReachable(6000));

    }


}

端口号

标记正在设备上运行的应用程序的,被规定为一个16位的二进制,范围是0~65535

分类

周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)

注册端口:1024~49151,分配给用户进程或某些应用程序。

动态端口:49151到65535,之所以被称为动态端口,是因为它一般不固定分配某种进程,而是动态分配。

注意:我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则会出错。

通信协议

网络上通信设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。

开放式互联网络互联标准:OSI 网络参考模型

OSI网络参考模型:全球网络互联标准
TCP/IP网络模型:事实上的国际标准
在这里插入图片描述

传输层的两个通信协议

UDP(User Datagram Protocol):用户数据报协议;
TCP(Transmission Control Protocol) :传输控制协议

UDP

特点:无连接、不可靠通信

不事先建立连接,数据按照包发,一包数据含:自己的IP、程序端口、目的IP、程序端口和数据(限制在64KB内)
发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,是不可靠的。

TCP

特点:面向连接、可靠通信。
TCP的最终目的:要保证在不可靠的信道上实现可靠传输。
TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。

在这里插入图片描述

在这里插入图片描述

UDP通信

特点:无连接、不可靠通信
不事先建立连接;发送端每次要把发送的数据(限制在64KB内)、接收端IP、等信息封装成一个数据包,发不出去就算了。
Java提供了一个Java.net.DatagramSocket类来实现UDP通信。

在这里插入图片描述

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.sql.SQLOutput;

public class Server {


    public static void main(String[] args) throws Exception
    {
        //1、创建一个服务对象(创建一个接韭菜的人)注册端口


        DatagramSocket socket =new DatagramSocket(
                6666);

        //2、创建一个数据包对象,用于接受数据的(创建一个韭菜盘子)
        byte[] buffer = new byte[1024*64];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            //3、开始正式使用数据包来接受客户端发来的数据
            socket.receive(packet);

            //4、从字节数组中,把接收到的数据直接打印出来
            //接受多少就到处多少
            //获取本次数据包接受了多少数据。

            int len = packet.getLength();

            String rs= new String(buffer,0,len);

            System.out.println(rs);
            System.out.println(packet.getAddress().getHostAddress());
            System.out.println(packet.getPort());
            System.out.println("----------------");
        }
    }
}


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception{
        //1、创建客户端对象
        DatagramSocket socket = new DatagramSocket();


        //2、创建数据包对象封装要发出去的数据(创建一个韭菜盒子)
        //public DatagramPacket(byte buf[],int length,InetAddress address,int port)
         //InetAddress address,int port)
        //参数1:封装要发出去的数据。
        //参数2:发出去的数据大小(字节个数)
        //参数3:服务器额的IP地址
        //参数4:服务程序的端口

        Scanner sc= new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg= sc.nextLine();
            if("exit".equals(msg)) {
                System.out.println("欢迎下次光临!推出成功!");
                socket.close();
                break;
            }
            byte[] bytes = msg.getBytes();
            DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),6666);

            //3、正式发送这个数据包的数据出去了

            socket.send(packet);

        }


    }
}



TCP通信

特点:面向连接、可靠通信

通信方面事先会采用”方式建立可靠连接“,实现端到端的通信;底层能保证数据成功传给服务器

java提供了一个Java.net.Socket类来实现TCP通信。


import java.io.DataInputStream;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLOutput;

public class Server {


    public static void main(String[] args) throws Exception
    {
        //1、创建ServerSocket的对象,同时为服务端注册端口
        ServerSocket serverSocket = new ServerSocket(8888);

        //2、从serverSocket对象,调用accept方法,等待客户端的连接请求
        Socket socket = serverSocket.accept();

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

        //4、把原始的字节输入流包装成数据输入流
        DataInputStream dis = new DataInputStream(is);

        //5、使用数据输入流读取客户端发过来的消息
         String rs=dis.readUTF();

         System.out.println(rs);
         //其实我们也可以获取客户端的IP地址
        System.out.println(socket.getRemoteSocketAddress());

        dis.close();
        socket.close();

    }
}

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class Client {

    public static void main(String[] args) throws Exception{

       //1、创建Socket对象,并同时请求与服务端程序的连接
        Socket socket= new Socket("127.0.0.1",8888);

        //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os= socket.getOutputStream();


        //3、把低级字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);


        //4.开始写数据出去了
        dos.writeUTF("在一起号码!");

        dos.close();
        socket.close();

    }
}



下面是一个简单的Java程序,用于实现多个客户端同时通信:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class MultiClientServer {

    private List<Socket> clients = new ArrayList<>();

    public static void main(String[] args) {
        MultiClientServer server = new MultiClientServer();
        server.start();
    }

    public void start() {
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            System.out.println("Server started");

            while (true) {
                Socket clientSocket = serverSocket.accept();
                clients.add(clientSocket);

                ClientHandler clientHandler = new ClientHandler(clientSocket);
                Thread clientThread = new Thread(clientHandler);
                clientThread.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private class ClientHandler implements Runnable {

        private Socket clientSocket;
        private BufferedReader reader;
        private PrintWriter writer;

        public ClientHandler(Socket clientSocket) {
            this.clientSocket = clientSocket;
            try {
                reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                writer = new PrintWriter(clientSocket.getOutputStream(), true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            try {
                String message;
                while ((message = reader.readLine()) != null) {
                    System.out.println("Received message: " + message);

                    // 向所有客户端发送消息
                    for (Socket client : clients) {
                        PrintWriter clientWriter = new PrintWriter(client.getOutputStream(), true);
                        clientWriter.println(message);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

这个程序创建了一个服务器端,可以同时处理多个客户端的连接。当一个客户端发送消息时,服务器会将该消息转发给所有连接的客户端。

运行这个程序后,可以使用多个客户端程序连接到服务器,并进行通信。每个客户端发送的消息都会被服务器广播给所有连接的客户端。

注意:这个程序是一个简单的示例,没有处理异常情况和并发安全性。在实际使用中,应该对异常进行处理并确保多个线程之间的安全访问。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【算法训练记录——Day42】

Day42——动态规划Ⅳ 1.leetcode_1049最后一块石头的重量II2.leetcode_494目标和3.leetcode_474一和零 1.leetcode_1049最后一块石头的重量II 思路&#xff1a;石头只能用一次。。。怎么才能让碰撞后重量最小呢&#xff0c;还要转换成动态规划&#xff0c;难以理解。。 看题解&…

J024_打印电影的全部信息

一、需求描述 展示多部电影的信息。 电影信息包括&#xff1a;电影名称、电影得分、电影票价格。 二、代码实现 2.1 Movie类 package com.itheima.collection;public class Movie {//电影名称private String name;//电影得分private int score;//电影票价格private double…

【Excel】输入内容自动添加边框线

1. 选中表格区域 → 新建条件规则 2. 设置公式 3. 设置格式 测试生效

[吃瓜教程]南瓜书第6章支持向量机

0.补充知识 0.1 超平面 定义&#xff1a; 超平面是指在&#x1d45b;维空间中&#xff0c;维度为 &#x1d45b;−1的子空间。它是分割空间的一个平面。 性质&#xff1a; n维空间的超平面 ( w T x b 0 , 其中 w , x ∈ R n ) (w^Tx_b0,其中w,x\in \mathbb R^n) (wTxb​0,其…

C++的set / multiset容器

一、介绍 C的set容器又被称为集合&#xff0c;所有元素在被插入后都会自动排序。 二、数据结构 set / multiset属于关联式容器&#xff0c;底层数据结构是用二叉树实现的。 其余的容器比如vector、deque和list等为序列式容器&#xff0c;因为他们底层使用线性序列结构&#xf…

Windows环境安装Redis和Redis Desktop Manager图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Redis概述 Redis是一个开源的高性能键值对数据库&#xff0c;以其卓越的读写速度而著称&#xff0c;广泛用于数据库、缓存和消息代理。它主要将数据存储在内存中&#xff0…

CISC和RISC指令集

文章目录 1. 指令集 2. CISC&#xff08;复杂指令集计算&#xff09; 3. RISC&#xff08;精简指令集计算&#xff09; 4. RISC的设计初衷 5. CISC和RISC流程对比 CISC&#xff08;复杂指令集计算&#xff09;的实现 RISC&#xff08;精简指令集计算&#xff09;的实现 …

【高中数学之函数】四种幂函数图线(二次、三次、开方、开立方)

【图像】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>UNASSIGNED</title><style type"text/css">.c…

【智能算法应用】灰狼算法求解二维栅格路径规划问题

目录 1.算法原理2.二维路径规划数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】灰狼算法&#xff08;GWO&#xff09;原理及实现 2.二维路径规划数学模型 栅格法模型最早由 W.E. Howden 于 1968 年提出&#xff0c;障碍物的栅格用黑色表示&#xff0c;可通…

基于pi控制的数字锁相环simulink建模与仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频&#xff09…

基于MATLAB的PEF湍流风场生成器模拟与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于MATLAB的PEF湍流风场生成器模拟与仿真。PEF&#xff08;Primitive Equations Formulation&#xff09;湍流风场模型&#xff0c;是大气科学和气象学中用来描述大气流动和气…

咬文嚼字:词元是当今生成式人工智能失败的一个重要原因

生成式人工智能模型处理文本的方式与人类不同。了解它们基于"标记"的内部环境可能有助于解释它们的一些奇怪行为和顽固的局限性。从 Gemma 这样的小型设备上模型到 OpenAI 业界领先的 GPT-4o 模型&#xff0c;大多数模型都建立在一种称为转换器的架构上。由于转换器在…

subset使用

在R语言中&#xff0c;subset()函数用于从数据框中选择满足特定条件的观测。其语法如下&#xff1a; subset(x, subset, select, drop FALSE) 参数说明&#xff1a; x&#xff1a;数据框或矩阵。 subset&#xff1a;逻辑条件&#xff0c;用于筛选满足特定条件的行。 select…

Linux Bridge - Part 2

概览 在前一篇文章中&#xff0c;我描述了Linux 网桥&#xff08;bridge&#xff09;的配置&#xff0c;并展示了一个实验&#xff0c;其中使用Wireshark来分析流量。在本文中&#xff0c;我将讨论当创建一个网桥时会发生什么&#xff0c;以及Linux 网桥&#xff08;bridge&am…

给您介绍工控CAN总线

CAN是什么 CAN&#xff0c;全称Controller Area Network&#xff0c;即控制器局域网&#xff0c;是一种由Bosch公司在1983年开发的通信协议。它主要用于汽车和工业环境中的电子设备之间的通信。CAN协议定义了物理层和数据链路层的通信机制&#xff0c;使得不同的设备能够通过CA…

数据驱动的内容优化:Kompas.ai如何提升内容表现

在数字化营销时代&#xff0c;内容是企业与用户沟通的重要桥梁。然而&#xff0c;随着信息量的爆炸性增长&#xff0c;如何让内容在激烈的竞争中脱颖而出&#xff0c;成为每个营销人员面临的问题。数据驱动的内容优化策略&#xff0c;通过精准分析和科学决策&#xff0c;帮助品…

基于Java+SpringMvc+Vue技术的实验室管理系统设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

基于Transformer的端到端的目标检测 | 读论文

本文正在参加 人工智能创作者扶持计划 提及到计算机视觉的目标检测&#xff0c;我们一般会最先想到卷积神经网络&#xff08;CNN&#xff09;&#xff0c;因为这算是目标检测领域的开山之作了&#xff0c;在很长的一段时间里人们都折服于卷积神经网络在图像处理领域的优势&…

SQLite 嵌入式数据库

目录&#xff1a; 一、SQLite 简介二、SQLite 数据库安装1、安装方式一&#xff1a;2、安装方式二&#xff1a; 三、SQLite 的命令用法1、创建、打开、退出数据库&#xff1a;2、编辑数据库&#xff1a; 四、SQLite 的编程操作1、打开 / 创建数据库的 C 接口&#xff1a;2、操作…

欧拉函数.

性质1&#xff1a;质数n的欧拉函数为n-1. 性质2&#xff1a;如果p&#xff0c;q都是质数&#xff0c;那么ϕ ( p ∗ q ) ϕ ( p ) ∗ ϕ ( q ) ( p − 1 ) ∗ ( q − 1 ) 证明&#xff1a;p&#xff0c;2p....q*p都不与q*p互质&#xff0c;q同理&#xff0c;所以总的不互质个…