网络编程原理二

本文涉及的产品
.cn 域名,1个 12个月
简介: 网络编程原理二

TCP / IP 协议



应用层

传输层

互联网层

数据链路层

物理层


image.png


一、应用层



应用层是我们网络编程主要针对的地方,也是程序员进行主要交互的一层。我们来看一些应用协议有哪些,以及应用层协议的两种形式。


1. 常用的现有应用层协议


DNS(域名系统)

HTTP(超文本传送协议)

FTP(文件传输协议)

Telnet(远程终端协议)


2. 自定义协议


开发之前,建立约定。开发过程中就会让客户端和服务器之间严格遵守协议约定好的格式。

自定义协议大体分成两类:


(1) 文本格式


文本格式即把请求响应当成字符串来处理,处理的基本单位是字符。

常见的文本格式有两类:xml,json

因为文本格式较为简单,当然自己也可以约定文本格式。


① xml

xml 是一种格式化组织数据的方式,它在 Java 标准库中有其对应的实现,这种格式不仅可以用于自定义协议,也可以用于网络传输。

格式如下:

整个 xml 是由 " 标签 " 构成的,此外,标签是成对出现的。


比方说: <num1> 10 </num1>
开始标签: <num1>  
结束标签: </num1>
中间值:   10
请求:               响应:
<request>             <response>
  <num1> 10 </num1>         <result> 30 </result>
  <num2> 20 </num2>       </response>
  <operator> + </operator>
</request>


② json


json 是一种键值对的方式,同样地,它在 Java 标准库中有其对应的实现。


格式如下:

键和值之间使用 [冒号] 分割,键值对之间使用 [逗号] 分割。


请求:               响应:
{                 {
  num1: 10,             result: 30
  num2: 20,           }
  operator: "+"
}


2) 二进制格式


把请求响应当成二进制数据处理,处理的基本单位是字节

protobuffer,thift…


3. 理解自定义协议


我们先来看一下以 【文本 + 分隔符】的方式,来自己设计一个协议。


UdpCalServer 用来描述服务器
UdpCalClient  用来描述客户端


(1) 基于 UDP 的 socket 写一个计算器运算


① UdpCalServer


package demo1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpCalServer {
    private DatagramSocket socket = null;
    public UdpCalServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while (true) {
            //2. 读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestPacket);
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            //3. 根据请求构造响应
            String response = process(request);
            //4. 构造响应并返回
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
                    response.getBytes().length, requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //顺便打印日志
            String log = String.format("[%s : %d], req: %s; resp: %s",
                    requestPacket.getAddress().toString(), requestPacket.getPort(),
                    request, response);
            System.out.println(log);
        }
    }
    private String process(String request) {
        String[] strings = request.split(";");
        if (strings.length != 3) {
            System.out.println("你所输入的格式不正确!");
            return null;
        }
        int num1 = Integer.parseInt(strings[0]);
        int num2 = Integer.parseInt(strings[1]);
        String key = strings[2];
        int result = 0;
        if (key.equals("+")){
            result = num1 + num2;
        } else if (key.equals("-")) {
            result = num1 - num2;
        } else if (key.equals("*")) {
            result = num1 * num2;
        } else {
            result = num1 / num2;
        }
        return result + "";
    }
    public static void main(String[] args) throws IOException {
        UdpCalServer server = new UdpCalServer(9090);
        server.start();
    }
}


② UdpCalClient


package demo1;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpCalClient {
    private String serverIp;
    private int serverPort;
    private DatagramSocket socket = null;
    public UdpCalClient(String serverIp, int serverPort) throws SocketException {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        this.socket = new DatagramSocket();
    }
    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入格式:num1; num2; +-*/ ");
        while (true) {
            System.out.println("输入计算的数和符号 ->");
            String request = scanner.nextLine();
            if (request.equals("exit")) {
                System.out.println("Exit!");
                return;
            }
            //1. 构造请求并发送
            DatagramPacket requestPacket = new DatagramPacket(
                    request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(serverIp), serverPort );
            socket.send(requestPacket);
            //2. 尝试获取响应
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            //3,显示响应结果
            String log = String.format("req: %s  resp: %s", request, response);
            System.out.println(log);
            System.out.println();
        }
    }
    public static void main(String[] args) throws IOException {
        UdpCalClient client = new UdpCalClient("127.0.0.1", 9090);
        client.start();
    }
}


通信结果:


a4e5e7d85c3a4b2ba46249500727d8e7.png


在上面的例子中,我们可以看到:当计算 15+3 = 18 这个逻辑的时候,我们在服务器与客户端通信之前,就两边约定好了,将操作数放在前两位,操作符放在后一位,它们之间通过 ; 来分割。也就说,格式为:【15;3;+】

所以说,自定义协议本质上也是一种提前的约定。


这个和我们开头说的例子是一样的:网友A 和 网友B 见面,他们提前就要告知对方今天穿什么颜色的上衣和裤子,否则就算到达同一地点,也很难找到找到彼此。


4. DNS


DNS:Domain Name System ( 域名系统 )


什么是域名?


类似于

www.baidu.com www.sogou.com


可以看到,域名就是通过一串单词通过点来进行分割的,在我们传统的叫法,域名实际上就是某某网站…


在传输数据的时候,先根据域名,再转换成对应的 IP地址,最后根据 IP地址进行传输。因为,IP地址是通过点分十进制来表示的,对于日常使用的网络用户来说,相对不好理解,而使用域名,就相当于为 IP地址 套上了一层外套,域名也就更加形象了。


二、传输层



传输层只负责端对端的数据传输,即只考虑起点和终点,不考虑中间过程。

传输层是操作系统内核实现的,因此谈到的传输层协议,一般都是指现成的一些协议,很少会涉及 " 自定制 "。


TCP / UDP 协议就是传输层中的主要协议。


1. 深入理解端口号


之前的博客提到:端口号其实是用来标识一个进程的。


一个主机中的所有进程都是通过同一个网卡来传输数据的,让每个进程分别绑定到不同的端口号,此时收到的网络数据报中就会包含一个 " 目的端口 ",它就会根据目的端口找到对应端口号的进程,从而把数据交给对应的进程。


2. 端口号和 PID 的区别


在学习线程的时候,我们了解过 PID 的概念,PID( Process Identification ),即进程标识符,操作系统里每打开一个程序都会创建一个进程 ID,即 PID. 但我们必须明确:程序在运行的时候,PID 是不会改变标识符的,但进程终止后,PID 标识符就会被系统回收,就可能会被继续分配给新运行的程序,所以说 PID 是临时的一个标志。


但是,端口号是固定不变的。


所以说:在网络编程中,我们指定一个程序 / 进程 与服务器通信,需要知道 主机的 IP地址 和 进程的端口号。而不能用 PID 来代替端口号!


举个例子:你打中国移动 10086,准备办理流量套餐,那么对面就会有人工客服接听电话,当你办理好了套餐之后,就把电话挂了。但你发现,电话套餐忘记办理了,于是就再次打电话过去,这个时候,你会发现,系统为你分配的客服和上一个客服就不再是同一个人了。那么,端口号就相当于 10086 这个固定的号码,而不同的客服就表示不同的 PID。


3. 注意


(1)


通常情况下,一个进程对应一个端口号,两个进程无法绑定同一个端口。


而比较常见的情况是:一个进程能够对应多个端口。这是通过 socket 文件和端口绑定来实现的,因为一个进程可以有多个文件,那么就可以做到让多个 socket 文件绑定到不同的端口。


让一个进程对应多个端口,实际上是为了解决【调试问题】,通常情况下,服务器会提供客户端一个【业务端口】,这个端口为客户端提供服务,如果在提供服务的时候,出现了数据问题怎么办?这时候,就可以事先让当前进程再绑定另一个【调试端口】,而这个端口就是用来定位一些问题。


(2)


端口号是一个两个字节整数,那么最多也就是 16 位,所以它的范围为 0- 65535.


知名端口号: 0 - 1023
注册端口号: 1024 - 49151
剩下的端口号叫动态端口号或私有端口号: 49152 - 65535


目录
相关文章
|
9天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习的奥秘:探索神经网络的核心原理
本文将深入浅出地介绍深度学习的基本概念,包括神经网络的结构、工作原理以及训练过程。我们将从最初的感知机模型出发,逐步深入到现代复杂的深度网络架构,并探讨如何通过反向传播算法优化网络权重。文章旨在为初学者提供一个清晰的深度学习入门指南,同时为有经验的研究者回顾和巩固基础知识。
33 11
|
1月前
|
机器学习/深度学习 存储 算法
回声状态网络(Echo State Networks,ESN)详细原理讲解及Python代码实现
本文详细介绍了回声状态网络(Echo State Networks, ESN)的基本概念、优点、缺点、储层计算范式,并提供了ESN的Python代码实现,包括不考虑和考虑超参数的两种ESN实现方式,以及使用ESN进行时间序列预测的示例。
61 4
回声状态网络(Echo State Networks,ESN)详细原理讲解及Python代码实现
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的自适应神经网络:原理与应用
【8月更文挑战第14天】在深度学习领域,自适应神经网络作为一种新兴技术,正逐渐改变我们处理数据和解决问题的方式。这种网络通过动态调整其结构和参数来适应输入数据的分布和特征,从而在无需人工干预的情况下实现最优性能。本文将深入探讨自适应神经网络的工作原理、关键技术及其在多个领域的实际应用,旨在为读者提供一个全面的视角,理解这一技术如何推动深度学习向更高效、更智能的方向发展。
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
深度剖析深度神经网络(DNN):原理、实现与应用
本文详细介绍了深度神经网络(DNN)的基本原理、核心算法及其具体操作步骤。DNN作为一种重要的人工智能工具,通过多层次的特征学习和权重调节,实现了复杂任务的高效解决。文章通过理论讲解与代码演示相结合的方式,帮助读者理解DNN的工作机制及实际应用。
|
4天前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【9月更文挑战第14天】网络协议是机器间交流的约定格式,确保信息准确传达。主要模型有OSI七层与TCP/IP模型,通过分层简化复杂网络环境。IP地址全局定位设备,MAC地址则在本地网络中定位。网络分层后,数据包层层封装,经由不同层次协议处理,最终通过Socket系统调用在应用层解析和响应。
|
5天前
|
网络协议 网络架构 数据格式
TCP/IP基础:工作原理、协议栈与网络层
TCP/IP(传输控制协议/互联网协议)是互联网通信的基础协议,支持数据传输和网络连接。本文详细阐述了其工作原理、协议栈构成及网络层功能。TCP/IP采用客户端/服务器模型,通过四个层次——应用层、传输层、网络层和数据链路层,确保数据可靠传输。网络层负责IP寻址、路由选择、分片重组及数据包传输,是TCP/IP的核心部分。理解TCP/IP有助于深入掌握互联网底层机制。
23 2
|
30天前
|
缓存 网络协议 算法
网络编程原理
网络编程原理
|
30天前
|
网络协议 算法 安全
网络原理问题
网络原理问题
|
1月前
|
机器学习/深度学习 人工智能 算法
深度学习的奥秘:探索神经网络的核心原理
深度学习,一个听起来既神秘又充满魔力的词汇,它如同一扇通往未知世界的大门,背后隐藏着无尽的智慧与可能。本文将以一种通俗易懂的方式,带领读者走进深度学习的世界,探索那些构成神经网络核心的基本原理。我们将从最初的感知机模型出发,逐步深入到复杂的多层网络结构,揭示数据如何在这些网络中流动、变化,最终实现智能决策的过程。通过这篇文章,你将了解到深度学习不仅仅是技术的堆砌,更是对自然界智慧的一种模仿与致敬。
45 1
|
17天前
|
存储 监控 安全