Java——网络编程(中)—TCP通讯(上)

一 (网络编程常用类)

(Java为了跨平台,在网络应用通信时是不允许直接调用操作系统接口的,而是由java.net包来提供网络功能。下面来介绍几个java.net包中的常用的类)

1 InetAddress类的使用

(封装计算机的IP地址和DNS)

(这个类没有构造方法——>如果要得到对象——>只能通过静态方法——>getLocalHost()、getByName()、 getAllByName()、 getAddress()、getHostName())

(获取本机信息——>getLocalHost方法创建对象)

(根据域名获取计算机的信息——>getByName(“域名”)

(根据IP获取计算机的信息——>getByName(“IP”))




1 作用

封装计算机的IP地址和DNS(没有端口信息)

注:DNS是Domain Name System,域名系统。

2 特点:

这个类没有构造方法。如果要得到对象,只能通过静态方法:getLocalHost()、getByName()、 getAllByName()、 getAddress()、getHostName()

3 获取本机信息——>getLocalHost方法创建对象

获取本机信息需要使用getLocalHost方法创建InetAddress对象。getLocalHost()方法返回一个InetAddress对象,这个对象包含了本机的IP地址,计算机名等信息。

public class InetTest {
  public static void main(String[] args)throws Exception {
    //实例化InetAddress对象
    InetAddress inetAddress = InetAddress.getLocalHost();
    //返回当前计算机的IP地址
    System.out.println(inetAddress.getHostAddress());
    //返回当前计算机名
    System.out.println(inetAddress.getHostName());
   }
}

4 根据域名获取计算机的信息——>getByName(“域名”)方法创建对象

根据域名获取计算机信息时需要使用getByName(“域名”)方法创建InetAddress对象。

public class InetTest2 {
  public static void main(String[] args)throws Exception {
    //实例化InetAddress对象
    InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
    //根据域名定位到服务器的这台计算机的IP地址(百度的ip地址)  
    System.out.println(inetAddress.getHostAddress());
    //根据域名定位到服务器的这台计算机的计算机名
    System.out.println(inetAddress.getHostName());
   }
}

(每次拿到的百度IP地址可能是不一样的,因为百度的IP地址不只有一个)

(体现了域名是不能定位互联网当中的唯一一台设备的——>能够定位互联网当中一个设备的唯一标识就是IP地址)

5 根据IP获取计算机的信息——>getByName(“IP”)方法创建对象

根据IP地址获取计算机信息时需要使用getByName(“IP”)方法创建InetAddress对象。

public class InetTest3 {
  public static void main(String[] args)throws Exception {
    //实例化InetAddress对象 
    InetAddress inetAddress = InetAddress.getByName("14.215.177.38");//百度IP
    //返回IP地址——>还是这个IP  
    System.out.println(inetAddress.getHostAddress());
    //返回计算机名——>返回的百度域名  
    System.out.println(inetAddress.getHostName());
   }
}










2 InetSocketAddress的使用

(IP地址+端口号”来区分不同的服务的,不依赖任何协议)

(可以实例化出来,new对象了)

(inetSocketAddress.getAddress().getHostAddress(),要先调用getAddress)



作用:包含IP和端口信息,常用于Socket通信。此类实现 IP 套接字地址(IP 地址 + 端口号),不依赖任何协议。

InetSocketAddress相比较InetAddress多了一个端口号,端口的作用:一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。

那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区分不同的服务的。

public class InetSocketTest {
  public static void main(String[] args) {
    InetSocketAddress inetSocketAddress = new InetSocketAddress("www.baidu.com",80);
    System.out.println(inetSocketAddress.getAddress().getHostAddress());
    System.out.println(inetSocketAddress.getHostName());
   }
}








3 URL类的使用

(IP地址——>标识了Internet上唯一的计算机,URL——>则标识了这些计算机上的资源)

(URL 代表一个统一资源定位符,它是指向互联网“资源”的指针)

(JDK中提供了URL类——>java.net.URL)

(和之前的File类一样——>磁盘里的文件或者是目录一并的可以封装成file对象,通过file对象当中所提供的方法,可以对磁盘当中的文件或者是目录进行相应的操作)

(Java net包里的url类也是这个作用,我们可以把这个字符串放到URL类当中做一个包装,把他变成URL对象,通过这个对象下所提供的API对URL进行相应的操作)





IP地址标识了Internet上唯一的计算机,而URL则标识了这些计算机上的资源。 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,有了这样一个类,就可以使用它的各种方法来对URL对象进行分割、合并等处理。

public class UrlTest {
  public static void main(String[] args)throws Exception {
      
    URL url = new URL("https://www.itbaizhan.com/search.html?kw=java");
    System.out.println("获取与此URL相关联协议的默认端口:"+url.getDefaultPort());
    System.out.println("访问资源:"+url.getFile());
    System.out.println("主机名"+url.getHost());
    System.out.println("访问资源路径:"+url.getPath());
    System.out.println("协议:"+url.getProtocol());
    System.out.println("参数部分:"+url.getQuery());
   }
}











4 URL实现简单的网络爬虫

(把这个URL地址这个字符串通过URL类做一个封装,通过调用OpenStream这个方法拿到一个字节输入流对象,再做一个流的转换,转换成字符串区读,就可以读到当前页面当中的内容了)

(百度搜索引擎——>有自己的网络爬虫去爬网络上的资源,然后把网络上的资源保存到自己的服务器里并建立索引,然后我们再通过百度搜索引擎去搜索时,根据关键字,它会根据我们所给定的关键字去找到对应的内容)




public class UrlTest2{
  public static void main(String[] args)throws Exception {					
      
      URL url = new URL("https://www.itbaizhan.com/");
      
      try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) {			//包装一下,用字符缓冲流
        StringBuilder sb = new StringBuilder();
        String temp;
            /* 
             * 这样就可以将网络内容下载到本地机器。
             * 然后进行数据分析,建立索引。这也是搜索引擎的第一步。
             */
        while ((temp = br.readLine()) != null) {
          sb.append(temp);
         }
        System.out.println(sb);


       } catch (Exception e) {
        e.printStackTrace();
       }
   }
}












二 (TCP通讯的实现)

1 TCP通信介绍

(基于请求和响应模式)

(在网络通讯中,第一次主动发起通讯的程序被称作客户端客户端,而在第一次通讯中等待连接的程序被称作服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别——>因为各自都有对方的对象)

(一旦建立套接字(Socket)连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。

——>套接字(Socket)——>与主机地址和端口地址相关联——>要知道IP和端口)

(ServerSocket——>最后也会返回一个Socket对象的——>在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket进行连接——>客户端和服务器通过套接字所建立的连接使用——>输入输出流(InputStream和OutputStream)进行通信——>使用TCP/IP可以发送任意数量的数据)

(三次握手是TCP协议之间的连接——>使用Socket去连serverSocket指的是客户端跟服务端的链接——>是建立在TCP协议链接通道的基础之上的——>基于TCP协议建立的两个设备连接,相当于我们打开了一个沟通的通
道,然后在这个沟通的通道当中,我们可以使用Socket和ServerSocket去进行数据的交互)








1 TCP通信实现原理

前边我们提到TCP协议是面向的连接的,在通信时客户端与服务器端必须建立连接。在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。

2 “请求-响应”模式:

  • Socket类:发送TCP消息。
  • ServerSocket类:创建服务器。

套接字Socket是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。换句话说,套接字起到通信端点的作用。单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。套接字与主机地址和端口地址相关联。主机地址就是客户端或服务器程序所在的主机的IP地址。端口地址是指客户端或服务器程序使用的主机的通信端口。

在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket进行连接,这样,客户端和服务器通过套接字所建立的连接使用输入输出流进行通信。

TCP/IP套接字是最可靠的双向流协议,使用TCP/IP可以发送任意数量的数据。

实际上,套接字只是计算机上已编号的端口。如果发送方和接收方计算机确定好端口,他们就可以通信了。

客户端与服务器端的通信关系图:
在这里插入图片描述

3 TCP/IP通信连接的简单过程:

位于A计算机上的TCP/IP软件向B计算机发送包含端口号的消息,B计算机的TCP/IP软件接收该消息,并进行检查,查看是否有它知道的程序正在该端口上接收消息。如果有,他就将该消息交给这个程序。

要使程序有效地运行,就必须有一个客户端和一个服务器。

4 通过Socket的编程顺序:

  1. 创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来的消息)
  2. ServerSocket调用accept()方法,使之处于阻塞状态。
  3. 创建客户端Socket,并设置服务器的IP及端口。
  4. 客户端发出连接请求,建立连接。
  5. 分别取得服务器和客户端Socket的InputStream和OutputStream。
  6. 利用Socket和ServerSocket进行数据传输。
  7. 关闭流及Socket。










2 创建服务端

(1 创建ServerSocket对象——>给定端口)

(2 用完要关闭资源——>正好实现了AutoCloseable接囗——>在try-with-resources中关闭)

(3 accept()监听端口——>监听端口时没心思干别的了——>线程处于阻塞状态——>什么时候有客户端来链接它了解除阻塞——>accept()返回Socket,就是来链接他的那个客户端的对象对应的Socket对象——>从客户端读取数据,以及向客户端发出数据,都是通过这个Socket对象当中的IO流)

(4 连接成功后会得到与客户端对应的Socket对象,并解除线程阻塞——>通过客户端对应的Socket对象中的输入流对象(getInputStream())——>Inputstream的作用就是准备去获取客户端发送过来的消息)






public class BasicSocketServer {
  public static void main(String[] args) {


    System.out.println("服务器启动等待监听。。。。");
    //创建ServerSocket
    try(ServerSocket ss =new ServerSocket(8888);
      //监听8888端口,此时线程会处于阻塞状态。
      Socket socket = ss.accept();
      //连接成功后会得到与客户端对应的Socket对象,并解除线程阻塞。
      //通过客户端对应的Socket对象中的输入流对象,获取客户端发送过来的消息。
      BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))
     ){
      
      System.out.println(br.readLine());
     }catch(Exception e){
      e.printStackTrace();
      System.out.println("服务器启动失败。。。。");
     }
   }
}










3 创建客户端

(1 创建Socket对象——>给定服务端的IP地址——>和服务端监听的端口号

——>目前服务端在本机上,IP就是127.0.01)

(2 也需要关闭资源——>实现了AutoCloseable接囗——>在try-with-resources中关闭)

(3 创建向服务端发送消息的输出流对象,PrintWriter(socket.getOutputStream())

——>两个应用在通讯时,如果A向B发送消息,那么在A当中,必定是使用字节输出流outputStream发送的,然后目标在接收消息时必定是用inputStream字节输入流来读取消息的)





public class BasicSocketClient {
  public static void main(String[] args) {
    //创建Socket对象
    try(Socket socket =new Socket("127.0.01",8888);
      //创建向服务端发送消息的输出流对象。
      PrintWriter pw = new PrintWriter(socket.getOutputStream())){
      pw.println("服务端,您好!");
      pw.flush();
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}










4 单向通信—创建服务端

(单向通信是指通信双方中,一方固定为发送端,一方则固定为接收端,当A向B发送消息时,永远是A向B发送消息,B永远是被动的等待A发送消息)

(比如说现在去京东买东西,要在浏览器里输入京东的域名,或者使用京东的APP,打开京东的APP显示的是京东的首页,其实启动APP的时候,已经向京东的服务端发送请求了,请求京东的首页信息,京东的服务器接收到请求了,把首页的内容响应给你,也就是说京东的服务器永远是被动的等待你发送消息来请求他的资源)

(1 通过与客户端对应的Socket对象获取输出流对象——>要向客户端写信息)

(2 不能只接受客户端发送的一条消息就结束了——>要一直发送消息直到主动让他结束while(true)——> if(“exit”.equals(str)break;)





public class OneWaySocketServer {
  public static void main(String[] args) {
      
    System.out.println("服务端启动,开始监听。。。。。");
    try(ServerSocket serverSocket = new ServerSocket(8888);
      //监听8888端口,获与取客户端对应的Socket对象
      Socket socket = serverSocket.accept();
      //通过与客户端对应的Socket对象获取输入流对象
      BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        
        
      //通过与客户端对应的Socket对象获取输出流对象
      PrintWriter pw = new PrintWriter(socket.getOutputStream())){
      System.out.println("连接成功!");
        
        
        
      while(true){
        //读取客户端发送的消息
        String str = br.readLine();
        System.out.println("客户端说:"+str);
        if("exit".equals(str)){
          break;
         }
        pw.println(str);
        pw.flush();
       }
     }catch(Exception e){
      e.printStackTrace();
      System.out.println("服务端启动失败。。。。。");
     }
   }
}












5 单向通信—创建客户端

(1 获取与服务端对应的Socket对象)

(2 创建键盘输入对象)

(3 通过与服务端对应的Socket对象获取输出流对象)

(4 通过与服务端对应的Socket对象获取输入流对象)

(5 通过键盘输入获取需要向服务端发送的消息)

(6 不能只发送一条消息就结束了——>while(true)—>if(“exit”.equals(str))break;)

(7 读取服务端返回的消息)




public class OneWaySocketClient {
  public static void main(String[] args) {
      
    //获取与服务端对应的Socket对象
    try(Socket socket = new Socket("127.0.0.1",8888);
      //创建键盘输入对象
      Scanner scanner = new Scanner(System.in);
      //通过与服务端对应的Socket对象获取输出流对象
      PrintWriter pw = new PrintWriter(socket.getOutputStream());
      //通过与服务端对应的Socket对象获取输入流对象
      BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))){


      while(true){
        //通过键盘输入获取需要向服务端发送的消息
        String str = scanner.nextLine();
        
        //将消息发送到服务端
        pw.println(str);
        pw.flush();


        if("exit".equals(str)){
          break;
         }


        //读取服务端返回的消息
        String serverInput = br.readLine();
        System.out.println("服务端返回的:"+serverInput);


       }
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}

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

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

相关文章

SQL server学习05-查询数据表中的数据(上)

目录 一,基本格式 1,简单的SQL查询语句 2,关键字TOP 3,关键字DISTINCT 二,模糊查询 1,通配符 三,对结果集排序 1,不含关键字DISTINCT 2,含关键字DISTINCT 3&…

Gitlab ci/cd

关于gitlab ci/cd,就是实现DevOps的能力,即Development &Operations的缩写,也就是开发&运维。CI/CD 指的是软件开发的持续集成方法,我们可以持续构建、测试和部署软件。通过持续方法的迭代能使得我们减少在错误代码或者错…

Leetcode42-环形链表

题目 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使…

计算机网络错题

文章目录 码分复用透明传输差错检测停止-等待协议回退N帧协议CSMA/CD协议以太网交换机Vlanip地址的无分类编制方法ip地址的应用规划ip数据包的发送和转发过程路由信息协议IPI2016201720202022 2.5信道 码分复用 透明传输 差错检测 停止-等待协议 回退N帧协议 CSMA/CD协议 以太网…

改进系列(5):在ResNet网络添加SelfAttention自注意力层实现的遥感卫星下的土地利用情况图像分类

目录 1. ResNet介绍 2. SelfAttention 层 3. ResNet34 SelfAttention 4. 遥感卫星下的土地使用情况分类 4.1 土地使用情况数据集 4.2 训练 4.3 训练结果 4.4 推理 1. ResNet介绍 ResNet(残差网络)是一种深度卷积神经网络模型,由Ka…

ARM循环程序和子程序设计

1、计算下列两组数据的累加和并存入到sum1和 sum2 单元中。datal:0x12,0x935,0x17,0x100,0x95,0x345。 data2:0x357,0x778,0x129,0x188,0x190,0x155,0x167。 1.定义数据段 ;定义数据段,类型为data(表示为数据段),权限为可读可写(程序可以读取和修改这…

蓝桥杯刷题——day5

蓝桥杯刷题——day5 题目一题干解题思路一代码解题思路二代码 题目二题干解题思路代码 题目一 题干 给定n个整数 a1,a2,⋯ ,an,求它们两两相乘再相加的和,即: 示例一: 输入: 4 1 3 6 9 输出: 117 题目链…

1_linux系统网络性能如何优化——几种开源网络协议栈比较

之前合集《计算机网络从入门到放弃》第一阶段算是已经完成了。都是理论,没有实操,让“程序猿”很难受,操作性不如 Modbus发送的报文何时等到应答和 tcp通信测试报告单1——connect和send。开始是想看linux内核网络协议栈的源码,然…

opencv——识别图片颜色并绘制轮廓

图像边缘检测 本实验要用到Canny算法,Canny边缘检测方法常被誉为边缘检测的最优方法。 首先,Canny算法的输入端应为图像的二值化结果,接收到二值化图像后,需要按照如下步骤进行: 高斯滤波。计算图像的梯度和方向。非极…

Edge SCDN深度解析,边缘安全加速的创新实践

边缘安全加速(Edge Secure Content Delivery Network,SCDN)是酷盾安全推出的边缘集分布式 DDoS 防护、CC 防护、WAF 防护、BOT 行为分析为一体的安全加速解决方案。通过边缘缓存技术,智能调度使用户就近获取所需内容,为…

软考高级架构 —— 10.6 大型网站系统架构演化实例 + 软件架构维护

10.6 大型网站系统架构演化实例 大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据,主要解决这类问题。 1. 单体架构 特点: 所有资源(应用程序、数据库、文件)集中在一台服务器上。适用场景: 小型网站&am…

Golang囊地鼠gopher

开发知识点-golang 介绍红队专题-Golang工具Fscan简介主要功能ubuntu 安装windows 安装常用命令:项目框架源文件common目录Plugins目录Webscan目录入口点插件扫描类型爆破插件common.ScantypeWebtitle函数webpoc扫描POC 执行CEL-GO 实践CEL指纹识别免杀源码特征参考链接红队专…

多分类交叉熵与稀疏分类交叉熵

总结: 标签为 One-hot 编码的多分类问题,用分类交叉熵对于标签为整数的多分类问题,用稀疏分类交叉熵稀疏分类交叉熵内部会将整数标签转换为 One-hot 编码,而如果标签已经是 One-hot 编码的形式,再使用稀疏分类交叉熵就会多此一举。 算例 假设我们有三个类别:A、B 和 C。…

360极速浏览器不支持看PDF

360安全浏览器采用的是基于IE内核和Chrome内核的双核浏览器。360极速浏览器是源自Chromium开源项目的浏览器,不但完美融合了IE内核引擎,而且实现了双核引擎的无缝切换。因此在速度上,360极速浏览器的极速体验感更佳。 展示自己的时候要在有优…

零基础微信小程序开发——小程序的宿主环境(保姆级教程+超详细)

🎥 作者简介: CSDN\阿里云\腾讯云\华为云开发社区优质创作者,专注分享大数据、Python、数据库、人工智能等领域的优质内容 🌸个人主页: 长风清留杨的博客 🍃形式准则: 无论成就大小,…

麒麟信安推出支持信创PC的新一代云桌面方案,助力政务信创高效安全运维

12月11日,在第二届国家新一代自主安全计算系统产业集群融通生态大会上,麒麟信安发布了支持信创PC的新一代云桌面方案,该方案是基于国际TCI架构实现国产PC机云化纳管在国内的首次发布,并与银河麒麟桌面操作系统、长城国产PC整机实现…

vim优化

1.编辑如下内容&#xff1a; cat > /root/.vimrc <<EOF set tabstop2 " 设置 Tab 为 2 个空格 set shiftwidth2 " 设置自动缩进为 2 个空格 set expandtab " 将 Tab 转换为空格 " 基本设置 set number syntax on" 快捷键设置…

hive—常用的日期函数

目录 1、current_date 当前日期 2、now() 或 current_timestamp() 当前时间 3、datediff(endDate, startDate) 计算日期相差天数 4、months_between(endDate, startDate) 日期相差月数 5、date_add(startDate, numDays) 日期加N天 6、date_sub(startDate, numDays) 日期减…

医学分割数据集肾结石分割数据集labelme格式359张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;359 标注数量(json文件个数)&#xff1a;359 标注类别数&#xff1a;1 标注类别名称:["kidney stone"] 每个类别标注的框数&…

Vulnstack红日安全内网域渗透靶场2实战攻略

一&#xff1a;环境搭建 新增的网卡VMnet2&#xff0c;ip调成10段。 PC配置如下&#xff1a; DC在该环境中充当是域控。DC配置如下 &#xff1a; WEB配置&#xff1a;需要两块网卡&#xff0c;相当于网关服务器。 作者把外网网段都写成了192.168.111.1/24&#xff0c;我们可以…