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

server/2024/12/18 6:22:33/

一 (网络编程常用类)

(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地址,计算机名等信息。

java">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对象。

java">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对象。

java">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地址+端口号”来区分不同的服务的。

java">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对象进行分割、合并等处理。

java">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这个方法拿到一个字节输入流对象,再做一个流的转换,转换成字符串区读,就可以读到当前页面当中的内容了)

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




java">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的作用就是准备去获取客户端发送过来的消息)






java">public class BasicSocketServer {public static void main(String[] args) {System.out.println("服务器启动等待监听。。。。");//创建ServerSockettry(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字节输入流来读取消息的)





java">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;)





java">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 读取服务端返回的消息)




java">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();}}
}

http://www.ppmy.cn/server/151102.html

相关文章

【Vue3学习】Vue3+setup语法糖+typeScript中的组件传值

一、父子组件传值 1. 子组件接收父组件的传值(父向子传值) 父组件 <template><div><ChildComponent name"Alice" :age"25" /></div> </template><script setup lang"ts">import ChildComponent from ./C…

计算机视觉中的特征提取算法

摘要&#xff1a; 本文聚焦于计算机视觉中的特征提取算法&#xff0c;深入探讨尺度不变特征变换&#xff08;SIFT&#xff09;算法。详细阐述 SIFT 算法的原理&#xff0c;包括尺度空间构建、关键点检测、方向分配与特征描述子生成等核心步骤。通过 C#、Python 和 C 三种编程语…

[Unity]Unity跨平台开发之Android入门

安卓环境配置 安装依赖项 推荐使用Unity Hub进行安装&#xff0c;安装时勾选Android Build Support、Android SDK & NDK Tools、OpenJDK。或者指定已安装的依赖项。&#xff08;注意&#xff1a;指定的依赖项需要是从UnityHub安装的。比如之前安装Unity2022时勾选了上述依…

JAVA2笔记第六章

第六章&#xff1a;反射设计模式 一、反射 1. 反射 (Reflection) &#xff1a;允许在程序运行状态中&#xff0c;可以获取任意类中的属性和方法&#xff0c;并且可以操作任意对象内部的属 性和方法&#xff0c;这种动态获取类的信息及动态操作对象的属性和方法对应的机制称…

Go vendor

博主在编写Go代码时&#xff0c;遇到了这样一个问题&#xff1a;想要修改某个外部包&#xff0c;添加几个函数&#xff0c;而其余功能继续使用&#xff0c;经过调研&#xff0c;发现可以将Go的外部包源码复制到项目本地&#xff0c;对包的代码进行修改&#xff0c;从而达到目的…

小程序自定义tab-bar,踩坑记录

从官方下载代码 https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 1、把custom-tab-bar 文件放置 pages同级 修改下 custom-tab-bar 下的 JS文件 Component({data: {selected: 0,color: "#7A7E83",selectedColor: "#3…

智能化API:如何重塑企业业务流程与用户体验

在数字化转型的浪潮中&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为企业和组织不可或缺的工具。API不仅允许不同应用程序和服务之间进行数据交换和功能整合&#xff0c;还通过其强大的连接性&#xff0c;将各个零散的服务串联成一个强大的整体。随着技术的不…

Qt5与Qt6中的高DPI缩放属性解析

在Qt5中&#xff0c;高DPI缩放默认是禁用的。为了启用它&#xff0c;开发者需要设置Qt::AA_EnableHighDpiScaling应用程序属性。然而&#xff0c;在Qt6中&#xff0c;高DPI缩放默认是启用的&#xff0c;并且不能被禁用。这种变化使得开发者在处理高分辨率屏幕时更加方便&#x…