IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Java 网络编程 - Socket -> 正文阅读

[网络协议]Java 网络编程 - Socket

作者:token keyword

1. 计算机网络结构

五层模型

该层的协议
应用层HTTP、FTP、SMTP…
传输层TCP、UDP…
网络层IP、ICMP…
链路层FDDI、PPP…
物理层IEEE…

各层次协议的数据单元

  • 应用层:报文(message)
  • 传输层:报文段(segment):TCP段,UDP数据报
  • 网络层:分组packet(如果无连接方式:数据报datagram)
  • 数据链路层:帧(frame)
  • 物理层:位(bit)

两个端点通信的过程

在这里插入ss描述图片来源 中科大郑烇、杨坚全套《计算机网络》

2. Socket 概念

Socket是两个主机间会话关系的标识(通过ip、port实现)。

Socket位于应用层和传输层之间,是传输层提供给应用层的服务,实现形式是Socket API。

在程序中Socket就是一个int 数(指向某一个会话,相当于句柄),这样是为了减少层间传输的信息量(不用每次要传本机ip、本机port、目标ip、目标port),简单,便于管理。

例:1001,1002表示了两个会话

Scoket数本机ip本机port目标ip目标port
10011.1.1.188882.2.2.280
10021.1.1.188882.2.2.2433

注:表中的两个会话虽然使用了同一个本地端口,但是能通过socket区分,所以可以同时进行通信。

TCP Socket

TCP Socket基于传输层的TCP协议,是一个四元组,包含本机ip、本机port、目标ip、目标port。
在基于TCP时,应用层向传输层传输时要提供 TCP Socekt 和 报文 两部分。在传输层被封装为报文段,网络层会通过TCP Socekt 提取目标ip+port进行寻址。

UDP Socket

UDP Socket基于传输层的UDP协议,是个二元组,包含本机ip、本机port。
在基于UDP时,应用层向传输层传输时要提供 UDP Socekt 、报文和目标ip+目标port 三部分。UDO Socekt和报文会被封装为数据报,目标ip+port则会通过传输层交给网络层进行寻址。

3. Java代码实现Socket通信

3.1 TCP通信

服务端

package com.alibaba.socket.server;

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

/**
 * @Date: 2022/4/18 17:21
 * @author: ZHX
 * @Description: 服务端简单使用TCPSocket进行通信,不考虑应用层的协议。
 * 步骤:
 * 1.创建Socket
 * 2.绑定服务端的ip、port.
 * 3.监听端口,阻塞式等待建立连接
 * 4.读
 * 5.处理
 * 6.发
 */
public class TCPSocketServer {

    public static void main(String[] args) throws IOException {
        method();
    }

    public static void method() throws IOException {
        //1.创建服务器Socket,并绑定本机ip+port 端口号默认是0.0.0.0 + 8888.
        // 客户端ip+port默认是*:*,接受所有ip的所有端口
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
            //2.监听端口, 获取监听到的Socket对象。阻塞式
            Socket accept = serverSocket.accept();

            //3.接受客户端请求.
            InputStream inputStream = accept.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            byte[] bytes = new byte[8192];
            bis.read(bytes);

            //4.处理数据
            String s = new String(bytes).toUpperCase();

            //5.处理完,响应给客户端
            OutputStream outputStream = accept.getOutputStream();
            outputStream.write(s.getBytes());
        }
    }
}

在这里插入图片描述

客户端

package com.alibaba.socket.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * @Date: 2022/4/18 17:21
 * @author: ZHX
 * @Description: 使用Socket简单实现客户端发送、接受数据。
 * 步骤:
 * 1.创建Socket对象
 * 2.绑定本机ip port 对方ip port
 * 3.建立连接
 * 4.发送请求
 * 5.输出响应内容
 */
public class TCPSocketClient {

    public static void main(String[] args) throws IOException {
        method();
    }

    public static void method() throws IOException {
        //1.创建Socket绑定本机ip+port和目标ip+port。并进行尝试连接
        // 本机ip+port 不写默认分配0.0.0.0:空闲的端口 .0.0.0.0
        // 服务器端的ip+port localhost:8888
        Socket socket = new Socket("localhost", 8888);//绑定目标ip+port,连接失败报异常
        
        //InetAddress不允许使用,我猜可能是因为DHCP ip不确定?
        //new Socket("localhost", 8888,new InetAddress(),7777);

        //2.连接成功,向服务器发送请求
        OutputStream outputStream = socket.getOutputStream();
        String content = "aaabbAbcd";
        outputStream.write(content.getBytes());
        //socket.shutdownOutput();//禁用该socket的输出流,不能再写了
        //outputStream.close();会同时关闭socket流.

        //3.接受服务器响应的数据并打印
        byte[] bytes = new byte[8192];
        InputStream inputStream = socket.getInputStream();
        
        /*
        //不能使用while != -1 因为不知道服务器发来的数据什么时候会发完,网络流无结束,可以自定义结束符http就是这样做的.
        int len = 0;
        while ((len = inputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes));
        }*/
        inputStream.read(bytes);//这里定义的数组足够大,都能读进来
        System.out.println(new String(bytes));
        //socket.shutdownInput();//禁用该socket的输入流,inputStream流并没有被关闭之后再读的数据都会被抛弃

        //5.因为这里我定义的bytes足够大,一次肯定都读完了就把socket流关闭。按理要和结束符配合的。
        outputStream.close();
        inputStream.close();
        socket.close();
    }
}

在这里插入图片描述

3.2 UDP通信

服务端

package com.alibaba.socket.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

/**
 * @Date: 2022/4/18 17:21
 * @author: ZHX
 * @Description: 服务端简单使用UPD Socket进行通信,不考虑应用层的协议。
 */
public class UDPSocketServer {

    public static void main(String[] args) throws IOException {
        method();
    }

    public static void method() throws IOException {

        //1.创建数据包套接字,绑定服务器本地的ip+port
        DatagramSocket socket = new DatagramSocket(new InetSocketAddress("localhost", 8888));

        byte[] bytes = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(bytes, 1024);
        while (true) {
            //2.监听端口8888,阻塞式的等待数据报
             socket.receive(receivePacket);

            //拿到数据报,简单打印下.
            byte[] data = receivePacket.getData();
            String s = new String(data, StandardCharsets.UTF_8);
            System.out.println(s);

            //3.处理数据
            s = s.toUpperCase();//小写转大写

            //4.响应给客户端,通过接受的数据报中的客户端Socket的ip和port(交给传输层时自动封装的的。).
            byte[] b = s.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(b, b.length, receivePacket.getAddress(), receivePacket.getPort());
            socket.send(sendPacket);
        }
    }
}

在这里插入图片描述
客户端

package com.alibaba.socket.client;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

/**
 * @Date: 2022/4/18 17:21
 * @author: ZHX
 * @Description: 使用Socket简单实现客户端发送、接受数据。
 * 步骤:UDP 无连接 直接发
 * 1. 创建UDP Socket对象
 * 2. 发送数据
 * 3. 关闭socket流
 */
public class UDPSocketClient {

    public static void main(String[] args) throws IOException {
        method();
    }

    public static void method() throws IOException {

        //UDP Socket是二元组,本地ip+port
        //1.创建UDP Socket(数据包套接字),绑定本机ip + 端口
        DatagramSocket socket = new DatagramSocket();//不写默认分配空闲端口

        //2.准备请求的数据 (如果要是应用层还要按照应用层协议封装数据)
        String content = "aaabbAbcd";
        byte[] bytes = content.getBytes();
        //3.将输入放入数据报,同时提供服务器的ip+port
        DatagramPacket datagramPacket = new DatagramPacket(content.getBytes(), bytes.length,new InetSocketAddress("localhost",8888));

        //4.直接发送,不用建立连接
        socket.send(datagramPacket);

        //5.接受服务器响应的数据报,阻塞式
        byte[] result = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(result,1024);
        socket.receive(receivePacket);
        //提取数据报中的数据,存到字节数组中
        byte[] data = receivePacket.getData();
        //简单打印下
        String s = new String(data, StandardCharsets.UTF_8);
        System.out.println(s);

        //4.关闭socket.
        socket.close();
    }
}

在这里插入图片描述

4. 参考资料

中科大郑烇、杨坚全套《计算机网络-自顶向下方法(第7版)》

JAVA Socket详解

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:15:05  更:2022-04-22 19:18:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:43:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码