网络编程原理:回显服务器与客户端通信交互功能

文章目录

  • 路由器及网络概念
  • 网络通信基础
  • TCP/IP 五层协议
  • 封装和分用
      • 封装
      • 分用
  • 网络编程(网络协议)
    • UDP类 API使用
      • 实现回显通信程序
        • 回显服务器(UDP代码)
        • 回显客户端(UDP代码)
    • TCP API使用
        • 回显服务器(TCP代码)
        • 回显客户端(TCP代码)

路由器及网络概念

网络发展是由单机时代->局域网时代->广域网时代->移动互联网时代
局域网:通过路由器的LAN为媒介来链接不同电脑,使其进行互相通信,而路由器通常为5个网口,1个WAN(用来连接上级的路由器)4个LAN。
当局域网连接的更多时,网络也会覆盖的更大。
在这里插入图片描述

交换机概念

交换机是因为路由器的LAN口过少,而需要连接到路由器的节点过多,这时候交换机的WAN通过连接路由器的LAN口,然后通过交换机的LAN口来连接其他的路由器的WAN或者电脑,来实现层层连接,构成更复杂的网络结构。

而广域网是通过更多的局域网的来连接到一起,构成的更加庞大的网络结构,覆盖一个城市或者更大。


网络通信基础

IP地址

描述一个设备,在网络中的地址,计算机中使用32位的字节数字来表示地址。
点分十进制
计算机地址由32位字节数构成,但是32位的byte字节过长,一般会表示为4个0~255之间的十进制数字,每个数字之间通过点进行分隔。
在这里插入图片描述


端口号

端口号:区分一个主机中不同的应用程序。
端口号是一个整数0~65535(2个字节)不同的程序可以关联/绑定相同的端口号,但是同一个主机上的应用程序,不能关联同一个端口号(一个端口号只能被一个程序绑定,而一个程序可以绑定多个端口)。
在实际的通信过程中,IP和端口是相互绑定的。


协议

在网络中,本质是通过光/电信号来传输数据,通过低电平表示1,高电平表示0 ,高频光信号表示1 ,低频光信号表示0。
协议就是通过一种约定,来约定通信的双方以同样的方式进行传输数据。


网络五元组

源IP 、源端口、目的IP、目的端口 、协议的类型,是在通信过程中必不可少的信息。


协议分层

通过对协议的定位或者是作用进行分类,将定位/作用相似放到同一层,然后通过上层协议调用下层协议,下层协议给上层协议提供支持。
通过协议分层不仅能够让多个层级直接交互配合,还可以对上层和下层彼此之间进行封装,使用上层协议,不必关注上层,使用下层协议不必关注下层。


TCP/IP 五层协议

物理层:描述网络通信的硬件设备
数据链路层:两个相邻节点之间的数据传输情况
网络层:进行路径规划,规划出最合适的路径
传输层:关注起点和终点
应用层:应用程序如何使用数据
在这里插入图片描述


封装和分用

封装

分装和分用描述了在网络通信中,基本的数据传输流程
1.应用层
开发者自定义通过设计数据报的格式,当用户通过输入进行传输,给打包成一个数据报来进行封装。
例如:当用户通过信息输入发送给另一个用户。
应用层协议(数据报格式):用户A(源头) 、 用户B(目的地)、时间 、发送的内容"hello"
转换为数据报:15239(源头)、 32643(目的地) 、2024-12-27 、hello
在这里插入图片描述


当应用层的数据报打包好后,可以通过调用下层协议,调用系统的API将数据传给数据层。
2.传输层

当到达传输层后,继续对应用层传输的数据进行打包,“拼接”。
在应用层的基础上进行拼接传输层的报头
UDP报头的关键信息:源端口和目的端口
在这里插入图片描述


网络层

网络层最主要的协议:IP协议,在原有的传输层的基础上进行拼接打包。
IP报头中包含的最重要的熟悉:源IP和目的IP
在这里插入图片描述


数据链路层

以太网:传输给数据链路层之后,通过以太网再次进行打包,通过拼接以太网报头来打包。
以太网包含的最重要信息:源mac地址和目的mac地址(描述一个设备在网络中的地址)

在这里插入图片描述
以下每一都是通过报头和载荷的形式进行封装,数据链路层通过报头和报尾来进行打包。每一次的传输都被封装成为一个载荷
在这里插入图片描述


物理层

当传输到物理层后,将这些打包好的数据转换成2禁止的0 1序列,通过光信号/电信号进行传输。


分用

当数据在传输给目的地(用户B)的时候,会经历一系列的交换机和路由器的转发。
当我们的的数据通过一系列步骤到达用户B后,这时候就需要进行分用解析这个包。
当接收时通过由物理层到应用层的步骤层层解析。

1.物理层

拿到光电信号后转换成二进制的数据,得到以太网的数据报。

2.数据链路层

通过以太网协议对物理层传输过来的数据报进行解析,得到报头和报尾和中间的载荷。

3.网络层

通过IP协议对数据对数据链路层传输过来的数据报进行解析,去掉IP报头得到载荷。

4.传输层

通过UDP协议,针对网络层传输的数据报进行解析,拿到载荷,去掉UDP报头,得到载荷。

5.应用层

根据端口号来负责将数据交给指定的应用程序,然后根据开发者自定义的应用层协议进行解析并显示。


网络编程(网络协议)

在计算机中,通过网络,可以让两个主机之间相互通信,在实现相互通信的过程时,需要我们开发者通过应用程序(应用层)通过系统的API与传输层进行交互。
Socket API这套协议,可以完成不同主机之间,不同系统之间的通信。

在传输层中,提供的网络协议主要由两个,UDP和TCP

UDP和TCP的区别

1.TCP可以进行连接,UPD不可以连接。
在计算机中,通过与双方建立连接,各自保存双方的信息。
如果TCP需要通信,需要建立连接,保存对方信息,才可以进行
UDP无需建立连接,就可以通信(虽然不需要建立连接,但是需要开发者通过socket API来进行对方信息作为参数进行传输)

2.TCP时可靠传输的,UDP时不可依靠传输的
网络通信中,A与B发送消息,消息有可能无法进行传输(传输的概率无法达成100%),可能存在物理干扰。
而可靠传输是当A与B发送消息时,如果发送失败,则需要采取一定的补救措施(重写发送等),这个可靠传输也无法保证必定传达成功,只是尽力补救。
当进行可靠传输时,则必定要付出一定的代价,这样的机制会复杂且传输的效率也会大大降低。

3.TCP是面向字节流的,UDP时面向数据报的
TCP通过以字节为单位进行传输,UDP以数据报为单位进行传输。

4.TCP和UDP都是全双工的
一个信道中,允许双向通信的,就是全双工。
一个信道中,只能单向通信的,就是半双工。

UDP类 API使用

DatagramSocket类

Socket是操作系统中的概念,是系统抽象出来的”文件“,本质Socket是属于网卡
当Socket在写数据时,相当于网卡在发送数据。
当Socket在读数据时,相当于网卡接收数据。

DatagramPacket类

通过此类,表示一个UDP的数据报(UDP面向的是数据报)
每次传输以UDP数据报为基本单位。


实现回显通信程序

编写服务器和客户端的代码通过回显显示在屏幕上
上述内容描述Socket本质是一个网卡,服务器则需要网卡中指定一个端口,但是客户端无须指定端口通过系统直接分配端口,防止程序端口冲突

回显服务器(UDP代码)
package UDPECHO;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    private DatagramSocket socket=null;//设置socket网卡
    public UdpEchoServer(int port) throws SocketException {
        socket=new DatagramSocket(port);//这里服务器需要指定端口
    }
    public void start() throws IOException {
        System.out.println("Server is Running");
        //这里receive接收客户端的请求,需要准备一个字节数组进行接收
        //这里的while循环只要不倒闭,服务器一直在循环状态
      while(true){
          DatagramPacket requestPacket=new DatagramPacket(new byte[5080],5080);
          socket.receive(requestPacket);
          //这里接收到请求将请求转换为String类型的字符串
          //这里的参数第一个是以字符串形式来获取字节数组,第二个参数表示下标,第三个表示最终的长度
          String request=new String(requestPacket.getData(),0,requestPacket.getLength());
          //对获取到的请求进行响应
          String response=process(request);
          //这里回应后开始准备继续返回给客户端影响的结果
          //这里的参数,第一个将响应继续转换为字节
          //参数2,因为是字符,所以需要转换为字节后在获取长度,如果是UTF-8的汉字则为三个字节
          //参数3,是传送给客户的地址,系统随机推送的地址
          DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
          socket.send(responsePacket);//socket里面的参数就是响应的结果,需要使用一个Packet参数
          //服务器打印的内容
          System.out.printf("[%s:%d] request:%s response:%s\n",requestPacket.getAddress(),requestPacket.getPort(),request,response);
      }
    }

    private String process(String request) {
        //返回响应,我们在程序中大部分都在维护响应中的代码,这里是回显,我们请求是什么响应就是什么
    return  request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server=new UdpEchoServer(8070);
        server.start();
    }
}


回显客户端(UDP代码)
package UDPECHO;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;

public class UdpEchoClient {
    private DatagramSocket socket=null;
    private String serverIp=" ";
    private int serverPort=0;
    public  UdpEchoClient(String ip,int port) throws SocketException {
        socket=new DatagramSocket();//默认随机指定端口
        serverIp=ip;
        serverPort=port;
    }
    public void start() throws IOException {
        System.out.println("Client is Running");
//            输入的内容
        Scanner scanner=new Scanner(System.in);
        while(true){
            System.out.println("Please enter:>");
            String request=scanner.next();//输入的内容
            //这里发送给服务器数据然后服务器进行接收
            //这里指定的是请求的内容长度,还有传送给服务器的IP地址和端口
            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
            socket.send(requestPacket);
            //客户端阻塞等待服务器传回来的数据,当服务器进行一系列操作后进行返回,接收服务器返回的
            DatagramPacket responsePacket=new DatagramPacket(new byte[5080],5080);//申请一个字节数组进行接收
            socket.receive(responsePacket);
            //最后将字节数组转换成字符串
            String response=new String(responsePacket.getData(),0,responsePacket.getLength());
            //打印显示到屏幕中
            System.out.println(response);
        }
    }
    public static void main(String[] args) throws IOException {
    UdpEchoClient client=new UdpEchoClient("127.0.0.1",8070);
    client.start();
    }
}


TCP API使用

ServerSocket类使用

针对服务器使用的类,来实现网卡,对客户端的请求进行操作,并最终将获取到的响应返回给客户端

Socket类使用

针对客户端的网卡,通过这个网卡来对服务器进行发起请求,并且接收服务器返回的响应,连接这两台机器的端点。


回显服务器(TCP代码)
package TCP;


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket=null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket=new ServerSocket(port);//填写服务器的端口号
    }
    public void start() throws IOException {
        ExecutorService thread=Executors.newCachedThreadPool();//创建一个线程池来进行并发执行
        System.out.println("Server is running.....");
      while(true){//多个客户端需要循环
          Socket clientSocket = serverSocket.accept();//通过此方法,将内核中已经建立好的连接拿出来给到Socket类型对象
          //这个方法包含请求回应响应
          thread.submit(new Runnable() {
              @Override
              public void run() {
                  try {
                      connection(clientSocket);
                  } catch (IOException e) {
                      throw new RuntimeException(e);
                  }
              }
          });
      }

    }

    private void connection(Socket clientSocket) throws IOException {
        //对客户端的上线进行日志打印
        System.out.printf("客户端上线Ip:%s,端口:%d\n",clientSocket.getInetAddress(),clientSocket.getPort());
        //这里通过流对象来进行输入和输出,通过try包裹来避免流对象后续的释放
        try(InputStream inputStream=clientSocket.getInputStream();
        OutputStream outputStream=clientSocket.getOutputStream();
            PrintWriter printWriter=new PrintWriter(outputStream)){
        while(true){//一个客户端在运行期间不只接收一次数据,需要循环控制
            Scanner scanner=new Scanner(inputStream);//这里来接收输入的内容
            if(!scanner.hasNext()){
                //这里条件说明客户端退出,下线日志进行打印
                System.out.printf("客户端下线,Ip:%s port:%d\n",clientSocket.getInetAddress(),clientSocket.getPort());
                break;
            }
            //这里对客户端传入给服务器的数据进行解析得到字符串
            String request=scanner.next();
            //对请求的数据进行响应并进行接收
            String response=process(request);
            //1.通过PrintWriter来将response传入给客户端
            printWriter.println(response);
            printWriter.flush();//刷新一下
            System.out.printf("[%s:%d] request:%s,response:%s\n",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);


        }
        }finally {
            //最后释放一下clientSocket对象,引用对象如果不释放,容易将文件描述符占满,导致文件泄漏
            clientSocket.close();
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server=new TcpEchoServer(8090);
        server.start();
    }
}


回显客户端(TCP代码)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class TcpEchoClient {
    private Socket socket=null;

    public TcpEchoClient(String serverIp,int serverPort) throws IOException {
        //这里的客户端需要与服务器进行连接,这是连接条件,ip和port为与服务器进行连接的条件
        socket=new Socket(serverIp,serverPort);
    }
    public void start() throws IOException {
        System.out.println("Client is Running......");
        Scanner scanner=new Scanner(System.in);
        //防止文件描述泄漏
       try(InputStream inputStream=socket.getInputStream();
           OutputStream outputStream=socket.getOutputStream();
           PrintWriter printWriter=new PrintWriter(outputStream);
           Scanner scannerNetwork=new Scanner(inputStream)){
           while(true){
               //1.输入
               System.out.print("enter:>");
               String request=scanner.next();//客户端控制台输入的内容
               //2.这里将数据发送给客户端
               printWriter.println(request);
               printWriter.flush();
               //3.接收服务器返回的数据
               String response=scannerNetwork.next();
               System.out.println(response);
           }
       }
    }
    public static void main(String[] args) throws IOException {
    TcpEchoClient client=new TcpEchoClient("127.0.0.1",8090);
    client.start();
    }
}

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946573.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云手机+Facebook:让科技与娱乐完美结合

移动互联网时代,Facebook作为全球最大的社交媒体平台之一,早已成为企业、品牌和组织竞相角逐的营销阵地。而云手机的出现,则为Facebook营销注入了新的活力,其独特的优势让营销活动更加高效、精准且灵活。本文将深入探讨云手机在Fa…

git使用指南-实践-搭建git私服

一.创建git私服的核心基础 所谓的git私服,其实就是在一个服务器上创建一个个的git仓库,并且这些仓库允许其在一个网络上被其他用户访问。 创建一个最素的git私服:随便找一台linux服务器,这里假设其ip为192.168.0.6,使…

KAFKA入门:原理架构解析

文章目录 一、认识kafka二、架构介绍2.1 工作流程2.2 Kafka可靠性保证2.3 Kafka存储 一、认识kafka Kafka到底是个啥?用来干嘛的? 官方定义如下: Kafka is used for building real-time data pipelines and streaming apps. It is horizont…

深度学习——损失函数汇总

1. 连续值损失函数 总结:主要使用胡贝儿损失函数,应用于连续数值的预测之间的误差损失,参考地址 import torch import torch.nn as nna = torch.tensor([[1, 2], [3, 4]], dtype=torch.float) b = torch.tensor([[3, 5], [8, 6]], dtype=torch.float)loss_fn1 = torch.nn.M…

2025.01.01(IO模型分类,超时检测,抓包分析,机械臂客户端)

作业&#xff1a;基于机械臂服务器写出客户端代码并执行 #include <myhead.h> #define IP "192.168.124.62" #define PORT 8888int main(int argc, const char *argv[]) {//1.创建套接字int cfd socket(AF_INET,SOCK_STREAM,0);if(cfd-1){perror("socke…

Pandas-数据透视表

文章目录 一. Pandas透视表概述1. pivot_table函数介绍 二. 栗子-零售会员数据分析1. 案例业务介绍2. 会员存量、增量分析① group by② 透视表③ 可视化 一. Pandas透视表概述 数据透视表&#xff08;Pivot Table&#xff09;是一种交互式的表&#xff0c;可以进行某些计算&am…

STM32-笔记26-WWDG窗口看门狗

一、简介 窗口看门狗用于监测单片机程序运行时效是否精准&#xff0c;主要检测软件异常&#xff0c;一般用于需要精准检测程序运行时间的场合。 窗口看门狗的本质是一个能产生系统复位信号和提前唤醒中断的6位计数器&#xff08;有的地方说7位。其实都无所谓&#xff0…

【超好用远程工具】跨平台SSH工具WindTerm免费开源

WindTerm WindTerm概述免费开源、免费开源、免费开源下载、安装屏幕截图主窗口 &#xff08;zsh&#xff09;&#xff1a;拆分视图&#xff1a;DigeWhite 主题&#xff1a; 基本设置连接到服务器SSH 连接Telnet 连接串口连接SFTP 连接使用多标签页 高级功能脚本和自动化会话管理…

开源存储详解-分布式存储与ceph

ceph体系结构 rados&#xff1a;reliable, autonomous, distributed object storage, rados rados采用c开发 对象存储 ceph严格意义讲只提供对象存储能力&#xff0c;ceph的块存储能力实际是基于对象存储库librados的rbd 对象存储特点 对象存储采用put/get/delete&#xf…

Postman[2] 入门——界面介绍

可参考官方 文档 Postman 导航 | Postman 官方帮助文档中文版Postman 拥有各种工具、视图和控件&#xff0c;帮助你管理 API 项目。本指南是对 Postman 主要界面区域的高级概述&#xff1a;https://postman.xiniushu.com/docs/getting-started/navigating-postman 1. Header&a…

牛客网最新1129道 Java 面试题及答案整理

前言 面试&#xff0c;跳槽&#xff0c;每天都在发生&#xff0c;而对程序员来说"金三银四"更是面试和跳槽的高峰期&#xff0c;跳槽&#xff0c;更是很常见的&#xff0c;对于每个人来说&#xff0c;跳槽的意义也各不相同&#xff0c;可能是一个人更向往一个更大的…

项目总结-ElasticSearch性能优化考虑点

项目总结-ElasticSearch性能优化考虑点 一、概述二、硬件层面优化2.1 ES硬件层面-内存优化2.2 ES硬件层面-磁盘优化2.3 ES硬件层面-CPU优化2.4 ES硬件层面-网络优化 三、系统层面优化3.1 ES系统层面-文件句柄数优化3.2 ES系统层面-swap优化 四、JVM层面优化4.1 JVM层面-JVM堆大…

Paperlib(论文管理工具)

Paperlib 是一个简单好用的论文管理工具。软件接入各学科数据库用于匹配论文元数据&#xff0c;逐步为每一个学科&#xff08;例如计算机科学&#xff0c;物理学等&#xff09;定制化数据库组合提高检索精度。尤其是精准的会议论文元数据检索能力。还可以管理你的论文&#xff…

静态时序分析:线负载模型的选择机制

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html 线负载模型及其选择 线负载模型仅在Design Compiler线负载模式&#xff08;非拓扑模式&#xff09;下时使用&#xff0c;它估算了导线长度和扇出对网线的电阻、电容和面积的影响&#xff…

深入探索Java中的List集合

一、ArrayList集合 1.ArrayList集合的特点 2.ArrayList集合的一些方法 ①.add(Object element) 向列表的尾部添加指定的元素。 ②.size() 返回列表中的元素个数。 ③.get(int index) 返回列表中指定位置的元素&#xff0c;index从0开始。 ④.add(int index, Object elemen…

Spark生态圈

Spark 主要用于替代Hadoop中的 MapReduce 计算模型。存储依然可以使用 HDFS&#xff0c;但是中间结果可以存放在内存中&#xff1b;调度可以使用 Spark 内置的&#xff0c;也可以使用更成熟的调度系统 YARN 等。 Spark有完善的生态圈&#xff1a; Spark Core&#xff1a;实现了…

DMDRS部署:搭建DM8-DM8数据同步

一、部署要求 1.1 硬件要求 DMDRS服务描述源DMDRS 内存要求至少2GB的内存空间。推荐配置4GB及以上的内存空间。 源DMDRS对内存空间的需求主要与装载的并发数相关。当内存空间配置低于2GB时&#xff0c;可以调整装载的线程数来降低源DMDRS对内存空间的需求。 磁盘要求至少10GB…

Flutter:打包apk,详细图文介绍

困扰了一天&#xff0c;终于能正常打包apk安装了&#xff0c;记录下打包的流程。建议参考我这篇文章时&#xff0c;同时看下官网的构建说明。 官网构建并发布 Android 应用详情 1、AS创建Flutter项目 2、cmd执行命令 生成一个sunluyi.jks的文件&#xff0c;可以自行把sunluyi替…

【电源专题】LDO关键DC参数——效率

在讲到电源的效率方面,很多时候网上最经常看到的是“LDO的效率低,开关电源效率高,所以LDO需要更大的散热器来帮助耗散热能”。 比如如下所示为网上找到的一些总结,一般也是大家所熟知的: 是的,这描述在一定的使用条件下是正确对的,但并不完全对,因为不同的工作…

互联网直播点播平台EasyDSS无人机视频推拉流技术实现工地远程监控巡检直播

在建筑行业&#xff0c;施工现场的安全管理和实时监控一直是项目管理中的重点。随着技术的进步&#xff0c;无人机工地直播技术成为了一种新兴的解决方案&#xff0c;它不仅能够提高施工透明度&#xff0c;还能够加强现场安全管理。EasyDSS作为一种先进的流媒体技术平台&#x…