Java基础 第五节 第二课

举报
我是小白呀iamarookie 发表于 2021/09/10 01:22:53 2021/09/10
【摘要】 TCP 通信程序 概述Socket 类构造方法成员方法 ServerSocket 类构造方法成员方法 简单的 TCP 网络程序TCP 通信分析图解客户端向服务器发送数据服务端实现客户端实现...

概述

TCP 通信能实现两台计算机之间的数据交互. 通信的两端, 要严格区分为客户端 (Client) 与服务端 (Server).

两端通信时步骤:

  1. 服务端程序, 需要事先启动, 等待客户端的连接
  2. 客户端主动连接服务器端, 连接成功才能通信. 服务端不可以住到连接客户端

在 Java 中, 提供了两个类用于事先 TCP 通信程序:

  1. 客户端: java.net.Socket类表示. 创建 Socket 对象, 向服务端发出连接请求. 服务端响应请求, 两者建立连接开始通信
  2. 服务端: java.net.ServerSocket类表示. 创建 ServerSocket 对象, 相当于开启一个服务, 并等待客户端的连接

Socket 类

Socket 类: 该类实现客户端套接字, 套接字指的是两台设备之间通讯的端点.

构造方法

public Socket(String host, int port)

  
 
  • 1

创建套接字对象并将其连接到指定主机的指定端口号. 如果指定的 host 是 null, 则相当于指定地址为会送地址.

注: 会送地址 (127.x.x.x) 是本机会送地址 (Lookback Address), 主要用于网络软件测试以及本地机进程通信. 无论什么程序, 一旦使用会送地址发送数据, 立刻返回, 不进行任何网络传输.

构造举例, 代码如下:

Socket client = new Socket("127.0.0.1", 6666);

  
 
  • 1

成员方法

public InputStream getInputStream(): 返回此套接字的输入流.

  • 如果此 Socket 具有相关联的通道, 则生成的 InputStream 的所有操作也关联该通道
  • 关闭生成的 InputStream 也将关闭相关的 Socket

public OutputStream getOutputStream(): 返回此套接字的输出流.

  • 如果此 Socket 具有相关联的通道, 则生成的 OutputStream 的所有操作也关联该通道
  • 关闭生成的 OutPutStream 也将关闭相关的 Socket

public void close(): 关闭此套接字.

  • 一旦一个 socket 被关闭, 它不可再使用
  • 关闭此 socket 也将关闭, 它不可再使用

public void shutdownOutput(): 禁用此套接的输出流

  • 任何前写出的数据将被发送, 随后终止输出流

ServerSocket 类

ServerSocket 类: 这个类实现了服务器套接字. 该对象等待通过网络的请求.

构造方法

public ServerSocket(int port)

  
 
  • 1

使用该构造方法在创建 ServerSocket 对象时. 就可以将其绑定到一个指定的端口号上, 参数 port 就是端口号.

构造举例, 代码如下:

ServerSocket server = new ServerSocket(6666);

  
 
  • 1

成员方法

public Socket accept(): 侦听并接受连接, 返回一个新的 Socket 对象. 用于和客户端实现通信. 该方法会一直阻塞直到建立连接.

简单的 TCP 网络程序

TCP 通信分析图解

  1. 服务端启动, 创建 ServerSocket 对象, 等待连接
  2. 客户端启动, 创建 Socket 对象, 请求连接
  3. 服务端接受连接, 调用 accept 方法, 并返回一个 Socket 对象
  4. 客户端 Socket 对象, 获取 OutputStream, 向服务端写出数据
  5. 服务端 Socket 对象, 获取 InputStream, 读取客户端发送的数据

(到此, 客户端向服务端发送数据成功)
在这里插入图片描述
(自此, 服务端向客户端会写数据)
6. 服务端 Socket 对象, 获取 OutputStream, 向客户端回写数据
7. 客服端 Socket 对象, 解析回写数据
8. 客户端释放资源, 断开连接

客户端向服务器发送数据

服务端实现

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTCP {
    public static void main(String[] args) throws IOException {
        System.out.println("服务端启动, 等待连接...");
        // 1. 创建ServerSocket 对象, 绑定端口, 开始等待连接
        ServerSocket ss = new ServerSocket(9999);
        // 2. 接收连接accept方法, 返回socket对象
        Socket server = ss.accept();
        // 3. 通过Socket获取输入流
        InputStream is = server.getInputStream();
        // 4. 一次性读取数据
        byte[] bytes = new byte[1024];  // 创建字节数组
        int len = is.read(bytes);  // 把数据读取到字节数组中
        String msg = new String(bytes, 0, len);  // 解析数组
        System.out.println(msg);  // 打印字符串信息
        // 5. 关闭资源
        is.close();
        server.close();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

客户端实现

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class ClientTCP {
    public static void main(String[] args) throws IOException {
        System.out.println("客户端, 发送数据...");
        // 1. 创建Socket(ip, port), 确定连接到哪里
        Socket client = new Socket("localhost", 9999);
        // 2. 获取流对象, 输出流
        OutputStream os = client.getOutputStream();
        // 3. 写出数据
        os.write("收到请回答".getBytes());
        // 4. 关闭资源
        os.close();
        client.close();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

服务器向客户端回写数据

服务端实现

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTCP {
    public static void main(String[] args) throws IOException {
        System.out.println("服务端启动, 等待连接...");
        // 1. 创建ServerSocket 对象, 绑定端口, 开始等待连接
        ServerSocket ss = new ServerSocket(9999);
        // 2. 接收连接accept方法, 返回socket对象
        Socket server = ss.accept();
        // 3. 通过Socket获取输入流
        InputStream is = server.getInputStream();
        // 4. 一次性读取数据
        byte[] bytes = new byte[1024];  // 创建字节数组
        int len = is.read(bytes);  // 把数据读取到字节数组中
        String msg = new String(bytes, 0, len);  // 解析数组
        System.out.println(msg);  // 打印字符串信息
        // ======================回写数据======================
        // 5. 通过Socket获取输出流
        OutputStream os = server.getOutputStream();
        // 6. 回写数据
        os.write("嗯嗯, 收到了".getBytes());
        // 7. 关闭资源
        os.close();
        is.close();
        server.close();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

客户端实现

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientTCP {
    public static void main(String[] args) throws IOException {
        System.out.println("客户端, 发送数据...");
        // 1. 创建Socket(ip, port), 确定连接到哪里
        Socket client = new Socket("localhost", 9999);
        // 2. 获取流对象, 输出流
        OutputStream os = client.getOutputStream();
        // 3. 写出数据
        os.write("收到请回答".getBytes());
        // ======================解析回写======================
        // 4. 通过Socket, 获取输入流对象
        InputStream is = client.getInputStream();
        // 5. 读取数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        String msg = new String(bytes, 0, len);
        System.out.println(msg);
        // 6. 关闭资源
        is.close();
        os.close();
        client.close();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

文章来源: iamarookie.blog.csdn.net,作者:我是小白呀,版权归原作者所有,如需转载,请联系作者。

原文链接:iamarookie.blog.csdn.net/article/details/111714671

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。