计算机网络(二)

2023-11-07

一、网络编程基础

1.1 为什么需要网络编程

丰富的网络资源,用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。
与本地打开视频文件类似,只是视频文件这个资源的来源是网络。
相比本地资源来说,网络提供了更为丰富的网络资源:
在这里插入图片描述所谓的网络资源,其实就是在网络中可以获取的各种数据资源。
而所有的网络资源,都是通过网络编程来进行数据传输

1.2 什么是网络编程

网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。
在这里插入图片描述
当然,我们只要满足进程不同就行;所以即便是同一个主机,只要是不同进程,基于网络来传输数据,也属于网络编程。
特殊的,对于开发来说,在条件有限的情况下,一般也都是在一个主机中运行多个进程来完成网络编程。
但是,我们一定要明确,我们的目的是提供网络上不同主机,基于网络来传输数据资源:

  • 进程A:编程来获取网络资源
  • 进程B:编程来提供网络资源

1.3 网络编程中的基本概念

(1)发送端和接收端

在一次网络数据传输时:
发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。
接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。
收发端:发送端和接收端两端,也简称为收发端。
注意:发送端和接收端只是相对的,只是一次网络数据传输产生数据流向后的概念。
在这里插入图片描述

(2)请求和响应

一般来说,获取一个网络资源,涉及到两次网络数据传输:
第一次:请求数据的发送
第二次:响应数据的发送
在这里插入图片描述

(3)客户端和服务端

服务端:在常见的网络数据传输场景下,把提供服务的一方进程,称为服务端,可以提供对外服务。
客户端:获取服务的一方进程,称为客户端。

对于服务来说,一般是提供:

  • 客户端获取服务资源
    在这里插入图片描述
  • 客户端保存资源在服务端

(4)常见的客户端服务器模型
最常见的场景,客户端是指给用户使用的程序,服务端是提供用户服务的程序:

  1. 客户端先发送请求到服务端
  2. 服务端根据请求数据,执行相应的业务处理
  3. 服务端返回响应:发送业务处理结果
  4. 客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果)
    在这里插入图片描述

(5) 客户端和服务器之间的交互方式

  • 一问一答
    客户端给服务器发送一个请求,服务器给客户端返回一个响应
  • 多问一答
    客户端发送多个请求,服务器返回一个响应,比如上传文件(文件过大时,需要拆分成个请求,多次上传)
  • 一问多答
    客户端发一个请求,服务器返回多个响应 ,比如下载文件(文件过大时,文件被拆分成多响应后返回)
  • 多问多答
    客户端发送多个请求,服务端返回多个响应,比如远程控制
    网络编程:通过写代码,实现两个/多个进程之间,通过网络,进行相互通信
    但之前我们学习进程时了解到进程具有隔离性,要想实现进程间通信,需要借助一个每个进程都能访问到的公共区域,完成数据交换
    网络编程其实也是进程间通信的一种方式,此处借助的公共区域就是网卡

(6)进行网络编程需要使用操作系统提供的API
在这里插入图片描述
传输层提供了网络通信的API,这些API也叫做socket API,操作系统提供的原生API,是C语言的,因此JVM就把C风格的socket api 封装了一下,变成了Java中面向对象风格的api

二、Socket套接字

2.1 概念

Socket套接字,是系统提供于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程

2.2 分类

Socket套接字主要针对传输层协议划分为如下三类:
(1)流套接字:使用传输层TCP协议
TCP的特点:

  • 有连接(类似于打电话,先建立连接,再进行通话)
  • 可靠传输(发送的数据对方收没收到,发送方有感知)
  • 面向字节流
  • 有接收和发送缓冲区
  • 大小不限

对于字节流来说,可以简单的理解为,传输数据是基于IO流,流式数据的特征就是在IO流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。
(2)数据报套接字:使用传输层UDP协议
UDP的特点

  • 无连接(类似于发微信,不必建立连接,可直接发送消息)
  • 不可靠传输(发送的数据对方收没收到,发送方并不关心)
  • 面向数据报
  • 有接受缓冲区,无发送缓冲区
  • 大小受限:依次最多传输64k

对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每接接收1个字节。
(3)原始套接字
原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据

2.3 Java数据报套接字通信模型

对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数
据报,一次接收全部的数据报。
java中使用UDP协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用DatagramPacket 作为发送或接收的UDP数据报。对于一次发送及接收UDP数据报的流程如下:

在这里插入图片描述
以上只是一次发送端的UDP数据报发送,及接收端的数据报接收,并没有返回的数据。也就是只有请
求,没有响应。对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,流程如下:
在这里插入图片描述

2.4 Java流套接字通信模型

在这里插入图片描述
【Socket编程注意事项】
在这里插入图片描述

  1. 客户端和服务端:开发时,经常是基于一个主机开启两个进程作为客户端和服务端,但真实的场景,一般是不同的主机
  2. 目的IP和目的端口号,标识了一次数据传输时要发送的数据的终点主机和进程
  3. Socket编程我们是使用流套接字和数据包套接字,基于传输层的TCP或UDP协议,但应用层协议,也需要考虑
  4. 端口占用问题,如果一个进程A已经绑定了一个端口,再启动一个进程B绑定该端口,就会报错,这种情况也叫端口被占用。对于java进程来说,端口被占用的常见报错信息如下v:
    5. v
    此时需要检查进程B绑定的是哪个端口,再查看该端口被哪个进程占用。以下为通过端口号查进程的方式:
  • 在cmd输入 netstat -ano | findstr 端口号 ,则可以显示对应进程的pid。如以下命令显示了70进程的pid

在这里插入图片描述

  • 再任务管理器中,通过进程PID找到对应的进程
    在这里插入图片描述
  • 如果占用端口的进程A不需要运行,就可以关闭A后,再启动需要绑定该端口的进程B
    如果需要运行A进程,则可以修改进程B的绑定端口,换为其他没有使用的端口。

2.5 UDP数据包套接字编程

DatagramSocket API

DatagramSocket 是UDP Socket,用于发送和接收UDP数据报
DatagramSocket构造方法:
在这里插入图片描述
DatagramSocket 方法:
在这里插入图片描述
【补充】:

  • DatagramSocket 属于是socket类,本质上相当于是一个"文件",在系统有一个种特殊的socket文件,这种文件对应到网卡设备,此时构造一个DatagramSocket对象, 就相当于是打开了一个内核中的socket文件
  • 打开socket文件之后,就能进行传输数据了

DatagramPacket API

DatagramPacket 是UDP Socket发送和接收的数据报
DatagramPacket 的构造方法:
在这里插入图片描述
DatagramPacket 方法:
在这里插入图片描述
构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。
InetSocketAddress API

InetSocketAddress ( SocketAddress 的子类 )构造方法:
在这里插入图片描述
【关于端口号】:

在操作系统中端口号的范围是0-65535,程序如果想要进行网络通信,就需要获取到一个端口号,端口号相当于用来在网络上区分进程的身份标识符(操作系统收到网卡的数据,就可以根据网络数据报中的端口号来决定要将这个数据交给哪个进程)
分配端口号有两种方式:程序员手动指定和系统自动分配

【UDP版本的回显服务器-客户端】(echo server)
服务器代码

package network;

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

public class UdpEchoServer {
    private DatagramSocket socket=null;
    public UdpEchoServer(int port) throws SocketException {
        //绑定一个端口,把这个服务器进程与一个端口号关联起来
        socket=new DatagramSocket(port);
    }
    public  void  start() throws IOException {
        System.out.println("服务器启动:");
        while (true){
            //去读客户端发来的请求
            DatagramPacket requsetPacket=new DatagramPacket(new byte[4096],4096);
            socket.receive(requsetPacket);
            //解析请求,根据DatagramPacket构造String
           String request=new String(requsetPacket.getData(),0, requsetPacket.getLength());
           //根据请求,构造响应
           String response=process(request);
           //将响应构造成DatagramPacket对象
            //response.getBytes().length不能写成response.length()
            //因为字节数组的长度不一定和字符串的长度相等,当字符串中包含中文字符时,两个长度一定是不相等的
           DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),0,response.getBytes().length
           ,requsetPacket.getSocketAddress());
           //requsetPacket.getSocketAddress()获取客户端的IP+端口
           //将响应放回给客户端
           socket.send(responsePacket);
            System.out.printf("[%s:%d] res=%s;resp=%s\n",requsetPacket.getAddress().toString(),
                    requsetPacket.getPort(),request,response);

        }
    }
    //根据请求计算响应的方法
    public  String process(String request){
        return request;
    }

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

客户端代码:

package network;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdpEchoClient {

   private DatagramSocket socket=null;
    public  UdpEchoClient() throws SocketException {
        //客户端的端口号,一般都是有操作系统自动分配
        socket= new DatagramSocket();
    }

    public void start() throws IOException {
        Scanner scanner=new Scanner(System.in);
        while (true){
            System.out.println(">");
            //由用户在控制台输入一个请求数据
            String request=scanner.next();
            //根据String 构造一个DatagramPacket对象
            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName("127.0.0.1"),8000);
            //将DatagramPacket对象发送给服务器
            socket.send(requestPacket);
           //从服务器读取响应数据
            DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
             String response=new String(responsePacket.getData(),0, responsePacket.getLength());
            System.out.printf("req:%s;resp:%s\n",request,response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client=new UdpEchoClient();
        client.start();
    }

}

【执行结果】
在这里插入图片描述

【同时启动多个客户端的设置过程】
在这里插入图片描述

【服务器端口号和客户端端口号】

服务器,端口号一般都是手动指定的,如果由操作系统自动分配,客户端就不知道服务器的端口号是多少,也就无法向客户端发送请求了
客户端,端口一般是自动分配的,因为客户端程序是安装在用户电脑上的,用户电脑当前运行哪些程序,是不可控的,如果要是手动指定端口,就可能发生端口冲突

【翻译服务器】(英译汉)

服务器代码:

package network;

import java.io.IOException;
import java.net.SocketException;
import java.security.PrivateKey;
import java.util.HashMap;

public class UdpDictServer  extends UdpEchoServer {
    private HashMap<String,String> dict=new HashMap<>();
    public UdpDictServer(int port) throws SocketException {
        super(port);
       dict.put("cat","小猫");
       dict.put("dog","小狗");
       dict.put("fuck","卧槽");

    }

    @Override
    public String process(String request) {
        return dict.getOrDefault(request,"这个俺也不会");
    }

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

客户端代码同上

2.6 TCP流套接字编程

ServerSocket API

ServerSocket是创建TCP服务端的Socket的API
ServerSocket构造方法
在这里插入图片描述
ServerSocket 方法:
在这里插入图片描述
Socket API
Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket。
不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。

Socket 构造方法
在这里插入图片描述
Socket方法
在这里插入图片描述
【说明】:

  • accept 方法没有参数,返回值是Socket对象,功能是等待有客户端和服务器建立连接,accept会把这个连接获取到进程中,进一步的通过返回值的Socket对象和客户端进行交互
  • Socket:服务器和客户端都会使用Socket,通过Socket对象,就可以进行发送/接收数据了,这里的传输数据,不是直接通过Socket对象,而是Socket内部包含了输入流(接收)和输出流(发送)对象

【举例理解ServerSocket和Socket的作用】

对于售楼来说,是有明确的分工的,有人是负责在外场拉客的,有人负责为拉到的客人提供服务
ServerSocket起到的作用就相当于是外场拉客
Socket起到的作用就相当于在内场提供服务

【TCP中的长连接与短链接】

TCP发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接。
短连接:每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收发数据。
长连接:不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。
区别:

  • 建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时的,长连接效率更高。
  • 主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发。
  • 两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等。

基于BIO(同步阻塞IO)的长连接会一直占用系统资源。对于并发要求很高的服务端系统来说,这样的消耗是不能承受的。
由于每个连接都需要不停的阻塞等待接收数据,所以每个连接都会在一个线程中运行。
一次阻塞等待对应着一次请求、响应,不停处理也就是长连接的特性:一直不关闭连接,不停的处理请求。
实际应用时,服务端一般是基于NIO(即同步非阻塞IO)来实现长连接,性能可以极大的提升。

【TCP版本的回显服务器-客户端】(echo server)
服务器代码:

package network;

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

public class TcpEchoServer {
    ServerSocket serverSocket=null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket=new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动:");
        while (true){
            Socket clientSocket=serverSocket.accept();
            processConnect(clientSocket);
        }
    }

    //长连接的版本
    private  void processConnect(Socket clinetSocket) throws IOException {
        System.out.printf("[%s %d] 建立连接\n",clinetSocket.getInetAddress().toString(),clinetSocket.getPort());
        try(InputStream inputStream=clinetSocket.getInputStream();
            OutputStream outputStream= clinetSocket.getOutputStream();){
            Scanner scanner=new Scanner(inputStream);
            PrintWriter printWriter=new PrintWriter(outputStream);
            while (true){
                if(!scanner.hasNext()){
                    System.out.printf("[%s %d] 断开连接\n",clinetSocket.getInetAddress().toString(),clinetSocket.getPort());
                    break;
                }
                //1.读取请求并解析
                String request=scanner.next();
                //2.根据请求计算相应
                String response=process(request);
                //3.将响应写回给客户端
                printWriter.println(response);
                printWriter.flush();
                System.out.printf("[%s %d] req:%s;resp:%s\n",clinetSocket.getInetAddress().toString(),clinetSocket.getPort(),
                        request,response);

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

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

客户端代码:

package network;

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=new Socket();
    public  TcpEchoClient() throws IOException {
        //需要和服务器建立连接
        //客户端new Socket的同时就是在与服务器建立连接的过程
        //需要指定服务器的IP地址和端口号
        socket=new Socket("127.0.0.1",8000);
    }
    public void start() throws IOException {
        //通过循环来实现长连接
        Scanner scanner=new Scanner(System.in);
        try(InputStream inputStream=socket.getInputStream();
            OutputStream outputStream= socket.getOutputStream()){
            Scanner scanner1=new Scanner(inputStream);
            PrintWriter printWriter=new PrintWriter(outputStream);
            while (true){
                System.out.println(">");
                //1.从控制台读取用户的请求
             String request=scanner.next();
             //2.将请求发送给服务器
             printWriter.println(request);
             printWriter.flush();
             //3.接收服务器的响应
                String response=scanner1.next();
             //4.将结果显示到界面上
                System.out.printf("req:%s;resp:%s\n",request,response);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        TcpEchoClient client=new TcpEchoClient();
        client.start();
    }
}

【注意细节】

  1. scanner.next的问题
    在这里插入图片描述
  2. clientSocket使用完要关闭
    ServerSocket的生命周期是跟随整个程序的,clientSocket的生命周期只是当前连接,在该连接使用完之后,应该及时关闭,如果不关闭,就会造成资源泄露,ServerSocket只有一个,clientSocket会有无数个,每个客户端与服务器好连接后都会有一个。
    在这里插入图片描述
  3. 使服务器能同时处理多个客户端的请求
    在这里插入图片描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机网络(二) 的相关文章

  • 是否可以将 char * 转换为结构?

    这是我的问题 rcvfrom 参数之一是 char 一旦我从中获取数据 我想将其转换为结构 然而选角并不成功 我究竟做错了什么 这是我所做的 struct int8 t seq int8 t ack bool flag char data
  • 在 Android 上显示实时 UDP 或 RTP 流(组播)

    我刚接触 Android 开发几周 我需要编写一个应用程序 可以向用户显示以 UDP 或 RDP 多播的实时流 该流位于诸如 rtp 230 0 0 11 1234 之类的地址 并通过该模块通过 WIFI 发出 我已经尝试从播放器 Daro
  • 是否可以在 socket.io 中使用 UDP?

    我正在开发一款游戏 听说 UDP 更适合实时游戏 我知道 socket io 使用 TCP 并且想知道是否有某种方法可以将其切换到 UDP 我尝试查找它 但只找到了 2012 年左右的帖子 其中说 UDP 仅在浏览器中处于实验阶段 从标准浏
  • UDP 数据报中发送的消息未经过净化?

    我的代码如下 一切都按照我想要的方式进行 但是当我的消息收到时 它们的末尾有很多框 有点像这样 消息 你好 如何才能让接收和打印的内容仅为 Message hello 我非常感谢任何帮助 import java io import java
  • C# UDP广播和接收示例

    问题 我正在尝试将 udp 套接字绑定到特定地址 我会广播一条消息 同一个套接字需要能够接收消息 当前代码 static void Main UdpClient Configuration new UdpClient new IPEndPo
  • memcached 使用 Django 监听 UDP

    Question 我无法获得memcached正在听UDP 上班 get set delete 与姜戈 我只让 memcached 监听UDP 11211 正如我在上一个问题 https stackoverflow com question
  • UDP 服务器套接字缓冲区溢出

    我正在 Linux 上编写 C 应用程序 我的应用程序有一个 UDP 服务器 它在某些事件上向客户端发送数据 UDP 服务器还接收来自客户端的一些反馈 确认 为了实现这个应用程序 我使用了一个 UDP 套接字 例如int fdSocket
  • Spark Scala UDP 在侦听端口上接收

    中提到的例子http spark apache org docs latest streaming programming guide html http spark apache org docs latest streaming pro
  • 从 ANDROID 2.2 发送 UDP 包(HTC 希望)

    我有一个局域网 我想从我的 android htcdesire 发送一条 udp 消息到我的电脑 它们之间有一个 WLAN 路由器 问题是 UPD 消息永远不会到达 PC Android上的代码 package org example an
  • 具有多个接口的 Python UDP 套接字

    我正在 Windows XP 机器上用 python2 7 编写脚本 本机使用不同的网卡连接到多个网络 我遇到了一个问题 我已将 UDP 套接字绑定到特定接口 我知道您可以通过仅提供网卡现有的 IP 地址来在 Windows 中完成此操作
  • HTTP 是否使用 UDP?

    这可能是一个愚蠢的问题 HTTP 是否使用过用户数据报协议 例如 如果使用 HTTP 传输 MP3 或视频 它内部是否使用 UDP 进行传输 From RFC 2616 http www ietf org rfc rfc2616 txt 通
  • 将 Docker 容器连接到网络接口/设备而不是 IP 地址

    经过仔细的研究 测试和摆弄 我只能找到通过从 IP 端口转发来将 Docker 容器连接到给定接口的方法 这可以通过添加来完成 p Host IP Host Port Container Port to a docker run命令 我有一
  • TCP 兼容性:为什么 TCP 不兼容数据包广播和组播操作?

    http en wikipedia org wiki User Datagram Protocol http en wikipedia org wiki User Datagram Protocol 与 TCP 不同 UDP 与数据包广播
  • 我刚刚在哪个适配器上收到此 UDP 数据包?

    我正在尝试用 C 编写一个 BOOTP 服务器 我正在接收并解析来自客户端的 BOOTP 数据包 我需要回复我的服务器 IP 地址 问题是 计算机可以有多个网络适配器 客户端还没有 IP 地址 有什么方法可以查出 UDP 数据包是在哪个适配
  • 对等网络应用程序的网络发现

    我希望有两个类 一个服务器类和一个客户端类 服务器类应该接收每个新客户端的 IP 地址和端口号并将它们存储在列表中 它应该为每个客户端提供已连接客户端及其 IP 地址的列表 然后 客户端可以使用 TCP 连接相互通信 问题是客户端不知道服务
  • Windows 操作系统中无法访问的 IP 套接字关闭时间

    这些代码通过用户数据报协议提供发送数据 下面有两个代码 当我使用第一个代码来处理无法访问的 IP 地址时 我得到了三秒的延迟 请查看新结果标题 只需打开新的 C 控制台应用程序并将这些代码粘贴到其中 第一个代码 using System u
  • 您可以bind()和connect() UDP连接的两端吗

    我正在编写一个点对点消息队列系统 它必须能够通过 UDP 运行 我可以任意选择一侧或另一侧作为 服务器 但这似乎不太正确 因为两端都从另一端发送和接收相同类型的数据 是否可以绑定 和连接 两端 以便它们只能彼此发送 接收 这似乎是一种非常对
  • Rails 是否支持侦听 UDP 套接字的简洁方式?

    在 Rails 中 集成更新模型某些元素的 UDP 侦听过程的最佳方式是什么 特别是向其中一个表添加行 简单的答案似乎是在同一进程中使用 UDP 套接字对象启动一个线程 但不清楚我应该在哪里执行适合 Rails 方式的操作 有没有一种巧妙的
  • F1 2019 UDP解码

    我目前正在为 F1 方向盘开发自己的显示器 F1 2019 由codemasters提供 通过UDP发送数据 该数据存储在字节数组中 我在解码返回的数组时遇到一些问题 问题是我得到了很多信息 但我不知道如何处理它们 我将向您介绍我所尝试过的
  • recvfrom() 中的 addrlen 字段有何用途?

    我在程序中使用 recvfrom 从我在 src addr 中指定的服务器获取 DGRAM 数据 但是 我不确定为什么需要初始化并传入addrlen 我读了手册页 但不太明白它的意思 如果src addr不为NULL 并且底层协议提供了源地

随机推荐

  • 网页参考资料

    1 w3school 2 蓝色理想 http www blueidea com 3 web前端开发 http www candoudou com
  • 福禄克铜缆测试参数:近端串扰和远端串扰参数之间的区别

    串扰指的是网线在传输网络信号中 产生了彼此的互相干扰 严重的时候会影响到网络传输得质量 网线的双绞程度越紧密 绞距越均匀时 其抗干扰的能力也会越强 且内部的串扰也会越小 在长距离网络传输中 效果也就越好 串扰会对具体的一对导线或整根电缆形成
  • linux 文件扫描程序 性能,Linux性能优化(三)——sysstat性能监控工具

    一 sysstat简介 1 sysstat简介 sysstat提供了Linux性能监控工具集 包括sar sadf mpstat iostat pidstat等 用于监控Linux系统性能和使用情况 iostat 提供CPU统计 存储I O
  • MFC异形对话框

    基本原理 获取窗体区域 指定一个颜色为透明色 遍历位图 将图上所有该色区域从窗体区域中去除 这样最后就得到了一个异形窗体 然后把背景图绘制在该窗体上 注意绘制的时候 作为透明的部分依然会被以原色绘制 但是由于绘制的地方并没有窗体 故而是显示
  • Java用链表实现队列

    链表实现队列 public class LinkedQueue class Node int val Node next public Node int val this val val public Node int val Node n
  • JQuery全部过滤选择器详细介绍上

    文章目录 JQuery全部过滤选择器详细介绍 上 基础过滤选择器 基础过滤选择器介绍 基础过滤选择器 应用实例 代码演示 内容过滤选择器 内容过滤选择器应用实例 代码演示 可见度过滤选择器 可见度过滤选择器 应用实例 代码演示 JQuery
  • 解决position:sticky元素有父盒子时不生效的问题

    当使用粘性定位的盒子出现 当滚动条滚动一段距离有效 然后就跟着滚动条滚出视口 不起作用了 要考虑看你是否设置了 html body height 100 这个代码会影响html和body的高度 不是整个视口的高度 参考 彻底理解粘性定位 p
  • Python期末大作业(学生成绩管理系统)

    学生成绩管理系统共分为五个主要功能 1 用户登陆和注册模块和退出 a 注册存入文件中 见文件 账号密码 csv b 用户登陆在文件中进行查询 见文件 账号密码 csv c 退出可以退出程序 2 新增学生数据 a 通过录入学生的姓名 学号 科
  • Thinkphp5进阶——02 日志

    1 存储位置 index php入口文件定义一个常量LOG PATH log php配置文件的path定义为常量LOG PATH index php 日志目录 define LOG PATH DIR log log php return 日
  • Vue使用Echarts在父子组件中传值问题

    最近项目上需要使用到Echarts做数据可视化 在写项目过程中发现在子组件中通过Echarts点击事件传值给父组件不起作用 研究了一下 发现是作用域问题 解决方法如下 原代码 通过保存外部作用域this得以解决 修改后代码
  • 刷题day68:零钱兑换

    题意描述 给你一个整数数组 coins 表示不同面额的硬币 以及一个整数 amount 表示总金额 计算并返回可以凑成总金额所需的 最少的硬币个数 如果没有任何一种硬币组合能组成总金额 返回 1 你可以认为每种硬币的数量是无限的 完全背包思
  • 一图曝光互联网大佬高考分数,厉害了

    往 期 趣 闻 程序员生日送什么蛋糕好 每日趣闻 人间真实 Java 版 后浪 每日趣闻 如何鉴别 996 公司 每日趣闻 一图读懂程序员 35 岁怎么转型 每日趣闻 程序员的难 领导不懂 每日趣闻 你点的每个 在看 我都认真当成了喜欢
  • How to resolve '_DllMain@12 already defined in xxx.obj' ?

    转自 http blog csdn net psusong article details 5858388 用Visual C 编写DLL 如果在new project时选了MFC DLL 而后又想写成Regular DLL 即拥有自己的D
  • 使用ksniff分析k8s pod的抓包分析

    使用ksniff分析k8s pod的抓包分析 ksniff是一个kubectl插件 利用tcpdump和Wireshark对Kubernetes集群中的任何pod进行远程捕获 可以得到Wireshark的全部功能 而对你正在运行的pods影
  • table表格中使用插槽

    效果图如下 实现代码如下
  • js 解决回调地狱的方法

    异步编程作为JavaScript中的一部分 具有非常重要的位置 它帮助我们避免同步代码带来的线程阻塞的同时 也为编码与阅读带来了一定的困难 过多的回调嵌套很容易会让我们陷入 回调地狱 中 使代码变成一团乱麻 为了解决 回调地狱 我们可以使用
  • “数字水印”来临,一波“反ChatGPT”的技术开始冒头

    数科星球 原创 作者丨数数 编辑丨十里香 ChatGPT爆火 对于这项技术来说 似乎无所不能 从作曲 小说 文章再到编剧 人们这些天为该项技术忙活的不亦乐乎 但事情很快得到了反转 有些人开始担心这项新的技术会被坏人所利用 而在版权界 生成式
  • 区块链学习笔记12——BTC思考

    区块链学习笔记12 BTC思考 学习视频 北京大学肖臻老师 区块链技术与应用 笔记参考 北京大学肖臻老师 区块链技术与应用 公开课系列笔记 目录导航页 哈希指针 BTC系统中很多地方用到了哈希指针 比如区块的块头就包含指向前一个区块的哈希指
  • MAC笔记本上搭建Vue环境

    1 安装Node js 打开终端 Terminal 在终端中输入以下命令安装Node js brew install node 如果你没有安装Homebrew 你可以在终端中输入以下命令安装 bin bash c curl fsSL htt
  • 计算机网络(二)

    目录 一 网络编程基础 1 1 为什么需要网络编程 1 2 什么是网络编程 1 3 网络编程中的基本概念 二 Socket套接字 2 1 概念 2 2 分类 2 3 Java数据报套接字通信模型 2 4 Java流套接字通信模型 2 5 U