Java——网络编程

这篇具有很好参考价值的文章主要介绍了Java——网络编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

网络编程基础类

InetAddress类

  • java.net.InetAddress类用来封装计算机的IP地址和DNS(没有端口信息),它包括一个主机名和一个ip地址,是java对IP地址的高层表示。大多数其他网络类都要用到这个类,包括Sorket、ServerSocker、URL、DatagramSorket、DatagramPacket等
  • 常用静态方法
    • getLocalHost()得到本机的InetAddress对象,其中封装了IP地址和主机名
    • getByName(String host)传入目标主机的名字或IP地址得到对应的InetAddress对象,其中封装了IP地址和主机名(底层会自动连接DNS服务器进行域名解析)
  • 常用实例方法
    • getHostAddress() 获取IP地址
    • getHostName() 获取主机名/域名
public class Test01 {
    public static void main(String[] args) throws UnknownHostException {
        //获取本机InetAddress对象(包含ip地址和封装对象)
        InetAddress ia = InetAddress.getLocalHost();

        //获取本机ip地址
        String ip = ia.getHostAddress();

        //获取本机主机名
        String hostName = ia.getHostName();

        System.out.println(ip + " -> " + hostName); //10.6.43.36 -> DESKTOP-D4BI28V

        //通过getByName(String host) 获取指定地址的InetAddress对象
        InetAddress baidu = InetAddress.getByName("baidu.com");
        System.out.println(baidu.getHostAddress()); //39.156.66.10
        System.out.println(baidu.getHostName()); //baidu.com
    }
}

URL类

  • URL由4部分组长城:协议、存放资源的主机域名、端口号、资源文件名。未指定端口号则使用协议默认的端口
  • 标准格式 <协议>://<域名/IP>:<端口号>/<路径>
    • <协议>://<域名/IP>是必须的
    • <端口号>/<路径>有时可省略
  • 为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,该类封装了大量复杂的涉及从远程站点获取信息的细节,可以使用它的各种方法来对URL对象进行分割、合并等处理
    • 构造方法
      • Url url = new URL(String url);
    • 常用方法
      • 获取协议
        • url.getPtotocol()
      • 获取域名
        • url.getHost()
      • 获取默认端口
        • url.getDefaultPort()
      • 获取端口
        • url.getPort()
      • 获取路径
        • url.getPath()
      • 获取资源
        • url.getFile()
      • 获取数据
        • url.getQuery()
      • 获取锚点
        • url.getRef()
public class Test01 {
    public static void main(String[] args) throws UnknownHostException, MalformedURLException {
        URL url = new URL("https://www.baidu.com/s?wd=%E5%BC%A0%E4%B8%89&rsv_spt=1&rsv_iqid=0x901ef519004b0a02&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=&tn=baiduhome_pg&ch=&rsv_enter=1&rsv_btype=i&rsv_dl=ib&inputT=2117");

        //获取协议
        String protocol = url.getProtocol();
        System.out.println("协议" + protocol);
        //获取域名
        String host = url.getHost();
        System.out.println("域名" + host);
        //获取默认端口
        int defaultPort = url.getDefaultPort();
        System.out.println("默认端口" + defaultPort);
        //获取端口
        int port = url.getPort();
        System.out.println("端口" + port);
        //获取路径
        String path = url.getPath();
        System.out.println("路径" + path);
        //获取资源
        String file = url.getFile();
        System.out.println("资源" + file);
        //获取数据
        String query = url.getQuery();
        System.out.println("数据" + query);
        //获取锚点
        String ref = url.getRef();
        System.out.println("锚点" + ref);
    }
}
    • 使用URL类的openStream()方法可以打开到此URL的连接并返回一个用于从该链接读入的InputStream,实现最简单的网络爬虫
public class Test01 {
    public static void main(String[] args){
        //获取URL对象指向tianqi.qq.com
        URL url = null;
        InputStream is = null;
        BufferedReader br = null;
        try {
            url = new URL("https://tianqi.qq.com/");

            //获取简单输入流
            is = url.openStream();

            //通过转换流获取包装流
            br = new BufferedReader(new InputStreamReader(is));


            String str = null;

            while ((str = br.readLine()) != null) {
                System.out.println(str);
            }
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        finally {
            //关闭流
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

TCP协议用到的类

Socket套接字类
  • 我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用传输层的服务呢?在应用层和传输层之间,则是使用套接Socket来进行分离。
  • 套接字就像是传输层为应用层开的一个小口,应用程序通过这个小口向远程发送数据,或者接收远程发来的数据。而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,是不知道也不需要知道的,也不会关心它如何传输,这属于网络其它层次工作。
  • Socket实际是传输层供给应用层的编程接口。Socket就是应用层与传输层之间的桥梁。使用Socket编程可以开发客户机和服务器应用程序,可以在本地网络上进行通信,也可通过Internet在全球范围内通信。

    Java——网络编程,Java,服务器,java

  • TCP协议和UDP协议是传输层的两种协议。Socket是传输层供给应用层的编程接口,所以Socket编程就分为TCP编程和UDP编程两类。
构造方法
  • public Socket(InetAddress a,int p)
    • 创建套接字并连接到指定IP地址的端口号
  • public Socket(String ip,int p)
    • 创建套接字并连接到指定IP地址的端口号
实例方法
    • getInetAddress()
      • 返回此Socket对象连接到的ip地址
    • getInputStream()
      • 返回此Soket对象的输入流(接收网络消息)
    • getOutputStream()
      • 返回此Soket对象的输出流(发送网络消息)
    • shutdownInput()
      • 禁用此Soket对象的输入流
    • shutdownOutput()
      • 禁用此Soket对象的输出流
    • close()
      • 关闭此Soket对象(默认会关闭IO流)
ServerSocket类
  • ServerSocket类用于实现服务器套接字(Server服务端)。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果
构造方法
    • public ServerSocket(int port)
实例方法
    • accept()
      • 侦听要连接此Socket并接受它
    • getInetAddress()
      • 返回此服务器套接字的本地地址
    • close()
      • 关闭此套接字

UDP协议用到的的类

DatagramPacket类
  • DatagramSocket类作为基于UDP协议的Socket,使用DatagramSocket类可以用于接收和发送数据,同时创建接收端时还需指定端口号
  • 构造方法
    • DatagramSocket()
      • 创建发送端的数据报套接字
    • DatagramSocket(int port)
      • 创建接收端的数据报套接字并指定端口号
  • 实例方法
    • send(DatagramPacket p)
      • 发送数据报
    • receive(DatagramPacket p)
      • 接收数据报
    • close()
      • 关闭数据报套接字
DatagramPacket类
  • DatagramPacket类负责把发送的数据打包(打包的数据为byte类型的数组),并且创建发送端时需指定接收端的IP地址和端口
  • 构造方法
    • DatagramPacket(byte bufp[],int offset,int length)
      • 创建接收端的数据
    • DatagramPacket(byte bufp[],int offset,int length,InetAddress address,int port)
      • 创建发送端的数据
  • 实例方法
    • public synchronized byte[] getDate()
      • 返回数据报中存储的数据
    • public synchronized int getLength()
      • 获得发送或接收数据报中的长度

基于TCP协议的程序

Java——网络编程,Java,服务器,java文章来源地址https://www.toymoban.com/news/detail-840642.html

服务端与客户端的单项通讯(client -> server)

public class Server {
    public static void main(String[] args) {
        //新建ServerSocket对象
        ServerSocket server = null;
        Socket client = null;
        BufferedReader br = null;
        try {

            int port = 8888;

            server = new ServerSocket(port);
            System.out.println("服务器启动成功,端口号为" + port);
            //服务端开始侦听并接收请求,获取到来自服务端的Socket对象
            client = server.accept();
            System.out.println("已经与" + client.getInetAddress() + ':' + client.getPort() + "建立连接");

            //获取服务端输入流
            br = new BufferedReader(new InputStreamReader(client.getInputStream()));
            System.out.println(br);

            String str = null;

            while ((str = br.readLine()) != null) {
                System.out.println("客户端:");
                System.out.println(str);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (server != null) {
                try {
                    server.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Client {
    public static void main(String[] args) {
        //创建客户端Socket对象
        Socket client = null;
        BufferedWriter bw = null;
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            client = new Socket(localHost,8888);
            //client = new Socket("127.0.0.1",8888); 传ip地址也可以

            //转换为增强字符流
            bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));

            Scanner sc = new Scanner(System.in);
            //发送内容
            while (true) {
                bw.write(sc.next() + '\n');
                bw.flush();
                Thread.sleep(1000L);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
  • 细节:readLine()是读一行,因此必须有换行符才能连续读取

服务端客户端双向通信(客户端--->服务端-->客户端)

public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        BufferedWriter bw = null;

        try {
            //新建服务器对象
            serverSocket = new ServerSocket(8888);

            //开始侦听8888端口接受连接并返回Socket套接字对象
            clientSocket = serverSocket.accept();
            System.out.println("已经连接到" + clientSocket.getInetAddress() + ':' + clientSocket.getPort());

            //获取缓冲字节输入/出流,缓冲字符输出流
            bis = new BufferedInputStream(clientSocket.getInputStream());
            bos = new BufferedOutputStream(new FileOutputStream("C:\\temp\\temp2.png"));
            bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

            byte[] bytes = new byte[1024];

            int i = 0;
            int len = 0;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes,0,len);
                //刷新缓冲流
                bos.flush();
            }

            bw.write("传输成功");
            //传输完成,返回信息
            bw.flush();

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (serverSocket == null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (clientSocket != null) {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Client {
    public static void main(String[] args) {
        Socket clientSocket = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;

        BufferedReader br = null;

        try {
            //创建客户端Socket
            clientSocket = new Socket(InetAddress.getLocalHost(),8888);
            //获取缓冲输出/入字节流,缓冲字符输入流
            bis = new BufferedInputStream(new FileInputStream(new File("C:\\temp\\temp1.png")));
            bos = new BufferedOutputStream(clientSocket.getOutputStream());
            br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            byte[] bytes = new byte[1024];
            //发送图片
            int len = 0;
            while ((len = bis.read(bytes)) != -1) {
                //发送图片
                bos.write(bytes,0,len);
                //刷新缓冲流
                bos.flush();
                len = bis.read(bytes);
            }

            //输出结束,Server端停止接收数据
            clientSocket.shutdownOutput();

            String str = null;
            //等待接收消息
            while ((str = br.readLine()) != null) {
                System.out.println(str);
            }


        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (clientSocket != null) {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
  • 细节
    • 服务端的输入流是从客户端得到的,客户端while循环结束后,服务器仍在监听客户端,等待客户端发送消息,因此客户端不会继续往下执行,必须调用shutdownOutput()方法,声明输出流已停止输出,客户端才会继续往下执行

基于UDP协议的程序

public class Recive {
    public static void main(String[] args) {
        DatagramSocket recive = null;
        DatagramPacket datagramPacket = null;
        try {
            //新建接收端DatagramSocket对象
            recive = new DatagramSocket(8888);

            //创建数据包
            byte[] bytes = new byte[1024];
            datagramPacket = new DatagramPacket(bytes,0,bytes.length);
            //接收数据报
            recive.receive(datagramPacket);

            //转实际长度
            System.out.println(new String(bytes,0,datagramPacket.getLength()));

        } catch (SocketException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (recive != null) {
                recive.close();
            }
        }
    }
}
public class Send {
    public static void main(String[] args) {
        DatagramSocket send = null;
        DatagramPacket datagramPacket = null;

        try {
            //新建发送端DatagramSocket对象
            send = new DatagramSocket();

            //准备要发送的数据
            byte[] bytes = "Hello,world".getBytes();

            //创建发送包
            datagramPacket = new DatagramPacket(bytes,0,bytes.length,InetAddress.getByName("127.0.0.1"),8888);
            //发送数据
            send.send(datagramPacket);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (send != null) {
                send.close();
            }
        }
    }
}

到了这里,关于Java——网络编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java【网络编程2】使用 TCP 的 Socket API 实现客户端服务器通信(保姆级教学, 附代码)

    📕各位读者好, 我是小陈, 这是我的个人主页 📗小陈还在持续努力学习编程, 努力通过博客输出所学知识 📘如果本篇对你有帮助, 烦请点赞关注支持一波, 感激不尽 📙 希望我的专栏能够帮助到你: JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统

    2024年02月05日
    浏览(62)
  • 【Linux网络编程】网络编程套接字(TCP服务器)

    作者:爱写代码的刚子 时间:2024.4.4 前言:本篇博客主要介绍TCP及其服务器编码 只介绍基于IPv4的socket网络编程,sockaddr_in中的成员struct in_addr sin_addr表示32位 的IP地址 但是我们通常用点分十进制的字符串表示IP地址,以下函数可以在字符串表示和in_addr表示之间转换 字符串转in

    2024年04月14日
    浏览(74)
  • 网络编程(一)TCP单进程服务器编程详解

    想要学习socket网络编程的读者一定要首先学好计算机网络的理论知识,包括 1)osi网络七层模型与ip四层模型 2)套接字含义 3)局域网通信过程 4)广域网通信过程 5)tcp,udp通信协议,在这两个协议中的连接建立,数据封装,传输过程,传输中可能遇到的问题的处理(差错控

    2024年02月15日
    浏览(43)
  • 【网络编程】demo版TCP网络服务器实现

    UDP和TCP的区别: 对于TCP协议有几个特点: 1️⃣ 传输层协议 2️⃣ 有连接(正式通信前要先建立连接) 3️⃣ 可靠传输(在内部帮我们做可靠传输工作) 4️⃣ 面向字节流 对于UDP协议有几个特点: 1️⃣ 传输层协议 2️⃣ 无连接 3️⃣ 不可靠传输 4️⃣ 面向数据报 可以看到

    2024年02月06日
    浏览(51)
  • 【网络编程】demo版UDP网络服务器实现

    在上一章【网络编程】socket套接字中我们讲述了TCP/UDP协议,这一篇就是简单实现一个UDP协议的网络服务器。 我们也讲过其实 网络通信的本质就是进程间通信 。而进程间通信无非就是读和写(IO)。 所以现在我们就要写一个服务端(server)接收数据,客户端(client)发送数据

    2024年02月02日
    浏览(44)
  • 网络编程: 服务器百万连接实现

    实验内容: 用三个客户端与服务器建立百万连接 服务器代码: Reactor 将实验遇到的问题记录如下 一个TCP连接叫做TCP控制块(tcp control block)。区分网络连接的五元组元素有 添加功能 增加服务器监听端口 如果服务器只用一个端口,那么至少需要10e6/(2^16-1024) ≈ 16台虚拟机。(能分

    2024年01月20日
    浏览(46)
  • 网络编程 lesson6 服务器模型和网络超时检测

    目录 服务器模型介绍 网络编程服务器模型 循环服务器模型 并发服务器模型 1. 多线程服务器 2. 多进程服务器 3. 事件驱动服务器 网络超时检测 应用场景 设置超时检测的方式 1.利用函数参数设置 代码示例 2.利用socket属性设置 3.利用alarm定时器设置 代码示例 在网络模型中,服

    2024年02月06日
    浏览(48)
  • 【skynet】 网络编程之回显服务器

    skynet 提供了一套 tcp 的 API ,本文将给出简单的回显服务器实现,以及讲解。 拉取 skynet 工程 编译 负责启动 gate 服务 \\\"L\\\" 表示客服端的消息前带四字节大端序的 msg_size skynet.address(skynet.self()) 把自己设置为 watchdog ,有新连接通过 text 消息告诉自己 port TCP 监听端口 0 将 TCP 数据

    2024年04月25日
    浏览(35)
  • linux并发服务器 —— linux网络编程(七)

    C/S结构 - 客户机/服务器;采用两层结构,服务器负责数据的管理,客户机负责完成与用户的交互;C/S结构中,服务器 - 后台服务,客户机 - 前台功能; 优点 1. 充分发挥客户端PC处理能力,先在客户端处理再提交服务器,响应速度快; 2. 操作界面好看,满足个性化需求; 3.

    2024年02月09日
    浏览(72)
  • 【网络编程】高性能并发服务器源码剖析

      hello !大家好呀! 欢迎大家来到我的网络编程系列之洪水网络攻击,在这篇文章中, 你将会学习到在网络编程中如何搭建一个高性能的并发服务器,并且我会给出源码进行剖析,以及手绘UML图来帮助大家来理解,希望能让大家更能了解网络编程技术!!! 希望这篇文章能

    2024年04月15日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包