网络编程原理二

本文涉及的产品
.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


目录
相关文章
|
25天前
|
网络协议 安全 5G
网络与通信原理
【10月更文挑战第14天】网络与通信原理涉及众多方面的知识,从信号处理到网络协议,从有线通信到无线通信,从差错控制到通信安全等。深入理解这些原理对于设计、构建和维护各种通信系统至关重要。随着技术的不断发展,网络与通信原理也在不断演进和完善,为我们的生活和工作带来了更多的便利和创新。
62 3
|
2月前
|
并行计算 安全 网络协议
探索未来网络:量子互联网的原理与应用
本文深入探讨了量子互联网的基本概念、技术原理及其潜在应用。通过对量子纠缠、量子叠加和量子隐形传态等核心概念的解释,文章展示了量子互联网如何利用量子力学特性来实现超高速、超高安全性的通信。此外,还讨论了量子互联网在金融、医疗、国防等领域的应用前景,以及当前面临的技术挑战和未来的发展方向。
72 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习的奥秘:探索神经网络的核心原理
本文将深入浅出地介绍深度学习的基本概念,包括神经网络的结构、工作原理以及训练过程。我们将从最初的感知机模型出发,逐步深入到现代复杂的深度网络架构,并探讨如何通过反向传播算法优化网络权重。文章旨在为初学者提供一个清晰的深度学习入门指南,同时为有经验的研究者回顾和巩固基础知识。
73 11
|
7天前
|
运维 物联网 网络虚拟化
网络功能虚拟化(NFV):定义、原理及应用前景
网络功能虚拟化(NFV):定义、原理及应用前景
23 3
|
18天前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
|
29天前
|
机器学习/深度学习 人工智能 监控
深入理解深度学习中的卷积神经网络(CNN):从原理到实践
【10月更文挑战第14天】深入理解深度学习中的卷积神经网络(CNN):从原理到实践
82 1
|
1月前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【10月更文挑战第10天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。
|
1月前
|
存储 安全 算法
网络安全与信息安全:构建数字世界的防线在数字化浪潮席卷全球的今天,网络安全与信息安全已成为维系现代社会正常运转的关键支柱。本文旨在深入探讨网络安全漏洞的成因与影响,剖析加密技术的原理与应用,并强调提升公众安全意识的重要性。通过这些综合性的知识分享,我们期望为读者提供一个全面而深刻的网络安全视角,助力个人与企业在数字时代中稳健前行。
本文聚焦网络安全与信息安全领域,详细阐述了网络安全漏洞的潜在威胁、加密技术的强大防护作用以及安全意识培养的紧迫性。通过对真实案例的分析,文章揭示了网络攻击的多样性和复杂性,强调了构建全方位、多层次防御体系的必要性。同时,结合当前技术发展趋势,展望了未来网络安全领域的新挑战与新机遇,呼吁社会各界共同努力,共筑数字世界的安全防线。
|
1月前
|
存储 安全 自动驾驶
探索未来网络:量子互联网的原理与应用
【10月更文挑战第2天】 本文旨在探讨量子互联网的基本原理、技术实现及其在通讯领域的革命性应用前景。量子互联网利用量子力学原理,如量子叠加和量子纠缠,来传输信息,有望大幅提升通信的安全性和速度。通过详细阐述量子密钥分发(QKD)、量子纠缠交换和量子中继等关键技术,本文揭示了量子互联网对未来信息社会的潜在影响。
|
18天前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9-2):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!