网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)(上)

本文涉及的产品
.cn 域名,1个 12个月
简介: 网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)

Java网络编程中的常用类


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


InetAddress的使用


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

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


特点:


这个类没有构造方法。如果要得到对象,只能通过静态方法:

getLocalHost()、getByName()、 getAllByName()、 getAddress()、getHostName()


获取本机信息


获取本机信息需要使用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());
   }
}


根据域名获取计算机的信息


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

public class InetTest2 {
    public static void main(String[] args)throws Exception {
        InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
      System.out.println(inetAddress.getHostAddress());
      System.out.println(inetAddress.getHostName());
   }
}


根据IP获取计算机的信息


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

public class InetTest3 {
    public static void main(String[] args)throws  Exception {
        InetAddress inetAddress = InetAddress.getByName("14.215.177.38");
      System.out.println(inetAddress.getHostAddress());
      System.out.println(inetAddress.getHostName());
   }
}


InetSocketAddress的使用


作用:包含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());
   }
}


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


通过URL实现

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通信的实现和项目案例


TCP通信实现原理


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


“请求-响应”模式:


Socket类:发送TCP消息。

ServerSocket类:创建服务器。


套接字Socket是一种进程间的数据交换机制。这些进程既可以在同 一机器上,也可以在通过网络连接的不同机器上。换句话说,套接 字起到通信端点的作用。单个套接字是一个端点,而一对套接字则 构成一个双向通信信道,使非关联进程可以在本地或通过网络进行 数据交换。一旦建立套接字连接,数据即可在相同或不同的系统中 双向或单向发送,直到其中一个端点关闭连接。套接字与主机地址 和端口地址相关联。主机地址就是客户端或服务器程序所在的主机 的IP地址。端口地址是指客户端或服务器程序使用的主机的通信端 口。 在客户端和服务器中,分别创建独立的Socket,并通过Socket的属 性,将两个Socket进行连接,这样,客户端和服务器通过套接字所 建立的连接使用输入输出流进行通信。 TCP/IP套接字是最可靠的双向流协议,使用TCP/IP可以发送任意数 量的数据。 实际上,套接字只是计算机上已编号的端口。如果发送方和接收方 计算机确定好端口,他们就可以通信了。 客户端与服务器端的通信关系图:


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


位于A计算机上的TCP/IP软件向B计算机发送包含端口号的消息,B 计算机的TCP/IP软件接收该消息,并进行检查,查看是否有它知道 的程序正在该端口上接收消息。如果有,他就将该消息交给这个程 序。 要使程序有效地运行,就必须有一个客户端和一个服务器。

 

通过Socket的编程顺序:


1 创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来 的消息)

2 ServerSocket调用accept()方法,使之处于阻塞状态。

3 创建客户端Socket,并设置服务器的IP及端口。

4 客户端发出连接请求,建立连接。

5 分别取得服务器和客户端Socket的InputStream和OutputStream。

6 利用Socket和ServerSocket进行数据传输。

7 关闭流及Socket。


TCP通信入门案例


创建服务端

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("服务器启动失败。。。。");
       }
   }
}


创建客户端

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


TCP单向通信


单向通信是指通信双方中,一方固定为发送端,一方则固定为接收 端。


创建服务端

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("服务端启动失败。。。。。");
       }
   }
}


创建客户端

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


TCP双向通信


双向通信是指通信双方中,任何一方都可为发送端,任何一方都可 为接收端。


创建服务端

public class TwoWaySocketServer {
    public static void main(String[] args) {
        System.out.println("服务端启动!监听端口8888。。。。");
        try(ServerSocket serverSocket  = new ServerSocket(8888);
            Socket socket = serverSocket.accept();
            //创建键盘输入对象
            Scanner scanner = new Scanner(System.in);
            //通过与客户端对应的Socket对象获取输入流对象
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //通过与客户单对应的Socket对象获取输出流对象
            PrintWriter pw  = new PrintWriter(socket.getOutputStream());){
            while(true){
                //读取客户端发送的消息
                String str = br.readLine();
                System.out.println("客户端说:"+str);
                String keyInput = scanner.nextLine();
                //发送到客户端
                pw.println(keyInput);
                pw.flush();
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}


创建客户端

public class TwoWaySocketClient {
    public static void main(String[] args) {
        try(Socket socket = new Socket("127.0.0.1", 8888);
            //创建键盘输入对象
            Scanner  scanner = new Scanner(System.in);
            //通过与服务端对应的Socket对象获取输入流对象
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //通过与服务端对应的Socket对象获取输出流对象
            PrintWriter pw = new PrintWriter(socket.getOutputStream());){
            while (true) {
                String keyInput = scanner.nextLine();
                pw.println(keyInput);
                pw.flush();
                String input = br.readLine();
                System.out.println("服务端说:" + input);
           }
       } catch (Exception e) {
            e.printStackTrace();
       }
   }
}


创建点对点的聊天应用


创建服务端

/**
* 发送消息线程
*/
class Send extends Thread{
    private Socket socket;
    public Send(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.sendMsg();
   }
    /**
     * 发送消息
     */
    private void sendMsg(){
        //创建Scanner对象
        try(Scanner scanner = new Scanner(System.in);
            //创建向对方输出消息的流对象
            PrintWriter pw = new PrintWriter(this.socket.getOutputStream());)
          {
            while(true){
                String msg = scanner.nextLine();
                pw.println(msg);
                pw.flush();
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
/**
* 接收消息的线程
*/
class Receive extends Thread{
    private Socket socket;
    public Receive(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.receiveMsg();
   }
    /**
     * 用于接收对方消息的方法
     */
    private void receiveMsg(){
        //创建用于接收对方发送消息的流对象
        try(BufferedReader  br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));){
            while(true){
                    String msg = br.readLine();
                    System.out.println("他说:"+msg);
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
public class ChatSocketServer {
    public static void main(String[] args) {
        try(ServerSocket serverSocket = new ServerSocket(8888);){
            System.out.println("服务端启动,等待连接。。。。。");
            Socket socket = serverSocket.accept();
            System.out.println("连接成功!");
            new Send(socket).start();
            new Receive(socket).start();
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}


网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)(下):https://developer.aliyun.com/article/1419280

目录
相关文章
|
9天前
|
存储 人工智能 自然语言处理
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
ChatMCP 是一款基于模型上下文协议(MCP)的 AI 聊天客户端,支持多语言和自动化安装。它能够与多种大型语言模型(LLM)如 OpenAI、Claude 和 OLLama 等进行交互,具备自动化安装 MCP 服务器、SSE 传输支持、自动选择服务器、聊天记录管理等功能。
75 15
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
|
3天前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
19 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
11天前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
37 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
3天前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
18 2
|
26天前
|
存储 监控 物联网
计算机网络的应用
计算机网络已深入现代生活的多个方面,包括通信与交流(电子邮件、即时通讯、社交媒体)、媒体与娱乐(在线媒体、在线游戏)、商务与经济(电子商务、远程办公)、教育与学习(在线教育平台)、物联网与智能家居、远程服务(远程医疗、智能交通系统)及数据存储与处理(云计算、数据共享与分析)。这些应用极大地方便了人们的生活,促进了社会的发展。
49 2
计算机网络的应用
|
29天前
|
机器学习/深度学习 运维 安全
图神经网络在欺诈检测与蛋白质功能预测中的应用概述
金融交易网络与蛋白质结构的共同特点是它们无法通过简单的欧几里得空间模型来准确描述,而是需要复杂的图结构来捕捉实体间的交互模式。传统深度学习方法在处理这类数据时效果不佳,图神经网络(GNNs)因此成为解决此类问题的关键技术。GNNs通过消息传递机制,能有效提取图结构中的深层特征,适用于欺诈检测和蛋白质功能预测等复杂网络建模任务。
66 2
图神经网络在欺诈检测与蛋白质功能预测中的应用概述
|
18天前
|
存储 安全 网络安全
网络安全的盾与剑:漏洞防御与加密技术的实战应用
在数字化浪潮中,网络安全成为保护信息资产的重中之重。本文将深入探讨网络安全的两个关键领域——安全漏洞的防御策略和加密技术的应用,通过具体案例分析常见的安全威胁,并提供实用的防护措施。同时,我们将展示如何利用Python编程语言实现简单的加密算法,增强读者的安全意识和技术能力。文章旨在为非专业读者提供一扇了解网络安全复杂世界的窗口,以及为专业人士提供可立即投入使用的技术参考。
|
26天前
|
安全 搜索推荐 网络安全
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
53 11
|
25天前
|
机器学习/深度学习 自然语言处理 语音技术
Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧
本文介绍了Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧,并通过TensorFlow和PyTorch等库展示了实现神经网络的具体示例,涵盖图像识别、语音识别等多个应用场景。
48 8
|
23天前
|
网络协议
计算机网络与通信
计算机网络基本概念:了解计算机网络的定义、功能、分类和拓扑结构(如总线型、星型、环型、树形、网状等)。 网络通信原理:了解网络通信的基本原理、协议和技术,如TCP/IP协议、网络通信设备等。
25 3