【计算机网络】socket编程

文章目录

  • 1. 网络通信的理解
  • 2.进程PID可以取代端口号吗?
  • 3. 认识TCP协议
  • 4. 认识 UDP协议
  • 5. socket编程接口
    • udp_server.hpp的代码解析
      • socket——创建 socket 文件描述符
      • Initserver——初始化
        • 1.创建套接字接口,打开网络文件
          • bind——绑定的使用
        • 2.给服务器指明IP地址和端口号
          • struct sockaddr_in的理解
          • bzero 清空
          • 代码实现
          • inet_addr ——字符串风格转化为4字节风格
          • 服务器自己指定IP地址
        • 3. 云服务器,或者一款服务器,一般不要指明某一个确定的IP
      • start ——启动
        • 1. 收到客户端发来的消息
          • recvfrom——获取用户数据报
          • inet_addr ——将4字节风格转为字符串风格
        • 2.将消息发给别人
          • sendto
    • udp_client.cc的代码解析
      • 客户端如何绑定?
      • 服务器为什么要自己绑定?
      • 代码实现
    • 完整代码
      • err.hpp (枚举错误码)
      • makefile
      • udp_client.cc(客户端的实现,无封装)
      • udp_clinet.hpp
      • udp_server.cc (有封装)
      • udp_server.hpp(服务器的实现)

1. 网络通信的理解

主机A将自己的数据交给主机B,就需要给主机B发送消息,主机B未来要给主机A回消息

但实际上 主机A将自己的数据交给主机B 并不是最终目的

如:你在淘宝上买了一件衣服,卖家发货后,从广东省发货 到 你所在的地区 ,最终包裹成功到达你的手上,你还需要决定这个快递该怎么用

数据的传送不是目的,让两台主机通过数据进行通信来协同完成任务才是目的


如:唐僧说要去西天去取经,唐僧所对应的寺庙是A主机,西天的大雷音寺是B主机,唐僧并不是到大类饮食就完了,这只是他的手段,
他还需要面见如来,如来会提供给他经书的服务


数据发起时,从主机A的传输层开始,交给主机B的传输层
而数据是从主机A的应用层中的某种客户端传来的
而将数据交给主机B的传输层不是直接目的,要把数据再交给应用层 中的某种服务器

主机A对应的客户端一定要启动起来,所以其本质是 进程

因为主机B的某种服务器在以进程的方式运行,所以可以随时随地能够访问某种服务

网络通信的本质是 进程间的通信


通信的第一个阶段:先将数据通过操作系统,将数据发送到目标主机(手段)
通信的第二个阶段:在本主机将收到的数据,推送给自己上层的指定进程

第一个阶段 可以通过TCP/IP协议完成,因为IP可以表示互联网上唯一的一台主机

当主机B的传输层把数据交给应用层,应用层对应的进程非常多
所以为了标识自己主机上网络进程的唯一性,提出了 端口号 的概念

端口号是传输层协议的字段,是一个2个字节16位的整数,用来标识系统层面上进程的唯一性

所以 IP地址 + 端口号 可以表示 互联网中唯一的一个进程

通信时,是有两个进程进行通信,所以就有源IP 和源 端口号 以及 目标IP 和目标 端口号
源IP 和源 端口号表示 互联网中唯一的一个进程
目标IP 和目标 端口号也表示 互联网中唯一的一个进程

所以 网络通信的本质 是通过IP+PORT号 构建唯一性,来进行网络进程间通信, 简称 套接字通信

2.进程PID可以取代端口号吗?

进程PID在系统层面上每个进程也是唯一的,也能表示该系统上进程的唯一性,所以用进程PID可以代替端口号的
但会存在一些问题
1.不是所有的进程都要进行网络通信,只有部分进程可能会网络通信,若用进程PID来作为网络标识该进程,就很难区分清楚那些是进行网络通信的,那些不是进行网络通信的

2. PID是操作系统进程管理的概念,网络模块也要包含进程管理的部分,要不然无法认识PID
增加了系统当中进程管理和网络管理的耦合度

3. 认识TCP协议

TCP协议(Transmission Control Protocol) 传输控制协议
特点:
传输层协议
面向连接
在通信过程中,会自带可靠性
面向字节流
在进行发和收数据时,在TCP层没有报文的概念,收到一堆的数据,把这一堆的东西一次将给上层的应用层,也可一个字节一个字节交
字节数据如何解释TCP不关心,只关心要都多少,给你多少,最终解释信息由应用层自己解释,这种从称之为字节流

4. 认识 UDP协议

UDP协议(User Datagram Protocol)用户数据报协议
特点:
传输层协议
无连接
不可靠传输
面向数据报
如:收快递,收一个就是一个完整的快递,具体的快递不可能收半个或者一个半,若对方发了三次,你就必须收三次

5. socket编程接口

实验室做出来一套进程间通信的标准,既可在本地通信,又可以在网络跨主机通信的标准 即 socket标准 隶属于 posix标准

最常见的为 基于网络通信的套接字 sockaddr_in

预间套接字 (使用在两个进程间使用本地进程通信的) sockaddr_un

套接字的设计者为了能够让所有人以 一套接口的方式 既能本地通信 又能网络通信,
所以设计出一个公共的数据结构 叫做 struct sockaddr
若想进行网络通信 (struct sockaddr_in) 或者 进行 本地通信 (struct sockaddr_un) ,使用 sockaddr 进行强制转换即可


在结构最开始时,都要有16位的地址类型
AF_INET 与AF_UNIX 实际上都是宏,用整数来表示的
将地址进行比较判断,
若等于 AF_INET,就为网络通信,把 sockaddr强转为 sockaddr_in
若等于 AF_UNIX,就为本地通信,把 sockaddr强转为 sockaddr_un


udp_server.hpp的代码解析

通过网络协议栈的通信功能 ,来把数据交付给对方的应用层,来完成双方进程的通信

将客户端的数据交给 服务端 ,就需要给服务端发送消息,服务端再给客户端回消息


在 udp_server.hpp 中 使用namspace 将命名空间 命名为 ns_server
其中再定义一个类 udpserver

socket——创建 socket 文件描述符

输入 man socket创建套接字

第一个参数 domain ,用于区分 进行网络通信还是 本地通信
若想为网络通信,则使用 AF_INET
若想为本地通信,则使用 AF_UNIX

第二个参数 type, 套接字对应的服务类型

在这里插入图片描述

SOCK_STREAM 流式套接
SOCK_DGRAM 无连接不可靠的通信(用户数据报)

第三个参数 protocol ,表示想用那种协议,协议默认为0
若为 流式套接,则系统会认为是TCP协议 ,若为用户数据报,则系统会认为是UDP协议

套接字的返回值:若成功则返回文件描述符,若失败则返回 -1

Initserver——初始化

1.创建套接字接口,打开网络文件

在这里插入图片描述
使用socket套接字,创建出 网络通信、UDP协议
若套接字返回-1表示失败,则初始化也就失败,程序就没有必要在继续运行了,所以使用exit终止程序

若套接字创建成功,则返回文件描述符
文件描述符的前三个分别被 标准输入 标准输出 标准错误占用,所以此时的文件描述符应该打印出3

bind——绑定的使用

输入 man 2 bind ,查看绑定

给一个套接字绑定一个名字
第一个参数 sockfd 为 文件描述符
第二个参数 addr 为 通用结构体类型
第三个参数 addrlen 为 第二个参数的实际长度大小

bind返回值:若成功,则返回0,若失败,返回 -1

2.给服务器指明IP地址和端口号

想要使用struct sockaddr_in类型 需添加头文件

定义一个 struct sockaddr_in(网络通信) 类型的 变量 local

struct sockaddr_in的理解

在这里插入图片描述
将 struct sockaddr_in 转到定义
16位地址类型:将 sa_prefix替换成 sin_ ,sin## family 实际上为 sin_family
此时的 sin_port 对应 当前绑定的端口号
sin_addr对应的是IP地址
再次将 in_addr转到定义,IP地址就是一个32位的整数

bzero 清空

sin_zero 作为 该结构体的填充字段
结构体可能很大,用不完,则使用填充字段将其填充上即可

输入 man bzero

将有n个字节的缓冲区,全部写为0

代码实现

在这里插入图片描述

将local对应的family(16位地址类型) 设置为 网络通信


设置一个私有的端口号port_


在这里插入图片描述
在类外设置一个端口号,用于构造时,若没有端口号传入,则8082充当缺省值


若我给你发消息,未来也需要将消息发回来,所以就必须知道我的IP地址和端口号
即端口号 以报文的形式发送到网络中

类内定义的port_,被称为本地主机序列, 需要把这个port_从主机序列 转成网络序列

输入 man htons ,表示短整数的主机转网络序列



定义一个私有的变量 ip_ 由于我们设置的IP地址是字符串风格的,而系统中的IP地址是4字节风格的 所以就需要将字符串风格的转化为 4字节风格的
inet_addr ——字符串风格转化为4字节风格

输入 man inet_addr

作用为:将字符串风格的IP地址 转化为 4字节风格的IP地址,并 默认会把主机序列 转换为 网络序列


由于local实际上定义在用户层的栈上,并没有在内核

所以借助bind,将填充好的套接字字段和文件字段,进行绑定关联,这样的文件才是网络文件
由于local 是 struct sock_addr_in 类型 ,需要强转为 struct sockaddr 公共类型


服务器自己指定IP地址

此时运行 udp_server可执行程序,会发现套接字创建成功,但绑定会失败


云服务器 不需要bind IP地址,需要让服务器自己指定IP地址


所以在main函数中添加命令行参数
命令行参数
main函数的两个参数,char* argv[] 为指针数组 ,argv为一张表,包含一个个指针,指针指向字符串
int argc,argc为数组的元素个数

设计一个usage函数,用以表示出 出现问题的可执行程序的名字 proc


再次创建一个err.hpp,使用enum枚举,将USAGE_ERR设置成1 ,默认将SOCKET_ERR(套接字报错)设置为2,
将 BIND_ERR(绑定错误)设置为3


通过argv数组的第二个下标指明字符串风格的端口号,再通过atoi将字符串转化为整数
最终只传入 端口号即可


在这里插入图片描述

3. 云服务器,或者一款服务器,一般不要指明某一个确定的IP

在这里插入图片描述

使用 INADDDR_ANY , 让udpserver在启动的时候,bind本主机上的任意IP


将 INADDDR_ANY 转到定义,实际上为缺省的0值


start ——启动

服务器本质是一个死循环,永远不退出
如:半夜打开王者荣耀,依旧可以玩


1. 收到客户端发来的消息

recvfrom——获取用户数据报

输入 man recvfrom, 获取用户数据报

第一个参数 sockfd 为 套接字
第二个参数 buf 为 自己定义的缓冲区
第三个参数 len 为 缓冲区的长度
第四个参数 flags 为读取方式,默认设为0,以阻塞方式读取
剩余两个参数 src_addr 和 addrlen 为 输入 输出型 参数
使用recvfrom收到数据,最终还要把数据还回去,想要还回去就必须知道别人是谁
src_addr 为 作为一个结构体,内部记录客户端的IP地址和端口号
addrlen 为 输出时结构体的大小
返回值:若大于0,则读取成功


定义一个 struct sockaddr_in(网络通信) 类型的 变量 peer
使用 len 来表示 未来的结构体大小

若n大于0,则读取成功,将最后一个位置的下一个位置设为\0
若读取失败,则继续读取


peer下的IP地址为 4字节整数,需要将其转为字符串风格

inet_addr ——将4字节风格转为字符串风格

输入 man inet_addr,将4字节IP转为字符串风格的IP


peer下的端口号为网络序列,想要获取客户端的端口号 clientport,需要使用 ntohs 将网络序列转为主机序列

2.将消息发给别人

sendto

输入 man sendto

第一个参数 sockfd 为 套接字
第二个参数 buf 为 自己定义的缓冲区
第三个参数 len 为 缓冲区的长度
第四个参数 flags 为读取方式,默认设为0,以阻塞方式读取
剩余两个参数 src_addr 和 addrlen 为 输入 输出型 参数
使用recvfrom收到数据,最终还要把数据还回去,想要还回去就必须知道别人是谁
src_addr 为 将以前收到的消息转会给客户端
addrlen 为 输出时结构体的大小
返回值:若大于0,则读取成功



udp_client.cc的代码解析

第一个参数 使用 AF_INET,表示网络通信
第二个参数 使用SOCK_DRAM,表示数据报
第三个参数 默认设为0,由于上述为数据报,所以为UDP协议


客户端如何绑定?

客户端是需要绑定的
socket通信的本质 是 客户端的IP与端口号 与 服务器的IP与端口号 进行网络版本的进程间通信
但客户端是不需要自己绑定的,由操作系统自动进行绑定
如:电脑和手机充满大量客户端,这些客户端来自于不同的企业,每个客户端的端口号不可以是固定的
必须让操作系统随机去选择,本质是为了防止确定的客户端被别人去占用,减少客户端层面的冲突
所以客户端的端口号要让操作系统随机分配,防止客户端出现启动冲突

服务器为什么要自己绑定?

1.服务器的端口 是 众所周知并不能随意改变的
如:110是报警电话,不可能报警电话每天都变,否则会导致当真正想打电话时都不知道打那个

2.服务器都是一家公司的,所以端口号需要统一规范化
如:淘宝不会把自己的服务部署到知乎上


代码实现

进行while循环,向服务器发送消息

目前没有消息,所以让用户输入充当消息源
使用 sendto,将消息发送给服务端

作为客户端将消息发送给 服务器主机
想要运行 客户端 ,就需要服务器的IP 和端口号


在这里插入图片描述
借助命令行参数,通过用户的输入的第二个参数 作为服务器的IP
用户输入的第三个作为 服务器的端口号

虽然此时服务器的IP和端口号知道了,但是想要借助sendto,后两个参数是需要套接字结构体


新建一个结构体server,内部包含服务器的IP和端口号
使用 htons ,将主机序列转为网络序列
使用inet_addr,将字符串转化为 4字节


在这里插入图片描述

此时 sendto的后两个参数 添加 创建的结构体 sever ,来完成发送服务器的任务
由于server 的类型 是 struct sockaddr_in ,而参数的类型为 公共结构体类型 struct sockaddr ,所以需要强转


使用 revfrom ,获取用户数据报
收到来自服务器转回来的消息 ,所以 定义一个 temp结构体,用于接收

在首次系统调用发送数据的时候,操作系统在底层随机选择客户端的端口号 加上自己的IP
先构建bind,再构建发送的数据报文

完整代码

err.hpp (枚举错误码)

#pragma once


enum 
{
    USAGE_ERR=1,
    SOCKET_ERR,
    BIND_ERR
};

makefile

.PHONY:all
all: udp_client udp_server

udp_client:udp_client.cc
	g++ -o  $@ $^ -std=c++11
udp_server:udp_server.cc
	g++ -o $@  $^ -std=c++11

.PHONY:clean
clean:
	rm -f udp_clinet udp_server
  

udp_client.cc(客户端的实现,无封装)

#include"udp_client.hpp"
#include"err.hpp"
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

static void usage(std::string proc)
{
    std::cout<<"usage:\n\t"<<proc<<"serverip serverport\n"<< std::endl;
}
// ./udp_client serverip sevrerport
int main(int argc ,char* argv[])//命令行参数 传入的是 客户端的运行 服务器的IP和端口号
{
  if(argc!=3)
  {
    std::cout<<" "<<std::endl;
    exit( USAGE_ERR);//终止程序
  }
   std::string serverip = argv[1];//服务器的IP
   uint16_t serverport =atoi(argv[2]);//服务器的端口号

  int sock=socket(AF_INET,SOCK_DGRAM,0);
  if(sock<0)//创建套接字失败
  {
     std::cout<<"create socket error"<<std::endl;
     exit( SOCKET_ERR);
  }

  //明确server是谁
  struct sockaddr_in server;//设置网络通信的结构体
  memset(&server,0,sizeof(server)); //将结构体清空
  server.sin_family=AF_INET;
  server.sin_port=htons(serverport);//端口号
  server.sin_addr.s_addr=inet_addr(serverip.c_str());//IP地址

  while(true)
  {
    //用户输入  
    std::string message;
    std::cout<<  "please enter# ";
    std::cin>> message;
    //发送消息
    sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));
   
   //接收消息
    char buffer[1024];
    struct sockaddr_in temp;
    socklen_t len=sizeof(temp);
    int n=recvfrom(sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&temp,&len);
    if(n>0)
    {
      buffer[n]=0;
      //收到回显消息
      std::cout<<"server echo"<<buffer<<std::endl;
    }
  }
    return 0;
}

udp_clinet.hpp

#pragma once
#include<iostream>
using namespace std;

udp_server.cc (有封装)

#include"udp_server.hpp"
#include"err.hpp"
#include<memory>
#include<string>
using namespace ns_server;
using namespace std;

static void usage(string proc)
{
    std::cout<<"usage:\n\t"<<proc<<"prot\n"<< std::endl;
}

//udp_server port
int main(int argc,char*argv[])//命令行参数
{
    if(argc!=2)//若命令行参数个数不为2,则当前会报错
    {
        usage(argv[0]);
        exit(USAGE_ERR);//终止程序
    }
    //端口号
    uint16_t port=atoi(argv[1]);//atoi可将字符串转化为整数

    //只需传入由用户指明的端口号
   unique_ptr<UdpServer> usvr(new UdpServer (port));

   usvr->Initserver();//服务器的初始化
   usvr->Start();//启动服务器
    return 0;
}






udp_server.hpp(服务器的实现)

#pragma once
#include<iostream>
#include<cerrno>
#include<cstring>
#include<cstdlib> 
#include<strings.h>
#include<functional>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include"err.hpp"

namespace  ns_server
{
  const static uint16_t  default_port=8082;//设置端口号为8082 
   class UdpServer
   {
     public:
       UdpServer(uint16_t port=default_port)//构造
       :port_(port)
       {}

      void  Initserver()//初始化
       {
        //1.创建套接字接口,打开网络文件
        sock_=socket(AF_INET,SOCK_DGRAM,0);
        if(sock_<0)//创建失败
        {
          //打印错误信息
            std::cout<<" create socket   error: "<<strerror(errno)<<std::endl;
            exit(SOCKET_ERR);//终止程序
        }
         std::cout<<"create socket success:"<<sock_<<std::endl;//3

         //2.给服务器指明IP地址和端口号
         struct sockaddr_in local;
        bzero(&local,sizeof(local));//全部置为0
        local.sin_family=AF_INET;//将16位地址类型 置为 网络通信
         local.sin_port=  htons(port_); //主机转网络的端口号

         //1.需要将字符串风格转化为 4字节
         //2.需要 将主机序列转换为 网络序列
         local.sin_addr.s_addr= INADDR_ANY ; //bind本机上的任意IP
         
         //bind 绑定
         int n=bind(sock_,(struct sockaddr*)&local,sizeof(local));
         if(n<0)//绑定失败
         {
           std::cout<<" bind  socket   error: "<<strerror(errno)<<std::endl;
           exit(BIND_ERR);
         }
           std::cout<<"bind socket success:"<<sock_<<std::endl;//3
       }
       void Start()//启动
       {
        char buffer[1024];//用于保护用户数据
         //设置一个死循环
           while(true)
           {
            //1.收到客户端发来的消息
             struct sockaddr_in peer;
             socklen_t len=sizeof(peer);//传入的缓冲区大小
             int n=recvfrom(sock_,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
             if(n>0)
             {
              buffer[n]='\0';
             }
             else 
             {
              //读取失败,则继续读取
              continue;
             }

             //提取客户端信息
             //4字节IP转为 字符串IP
             std::string clientip =inet_ntoa(peer.sin_addr);//客户端IP
             //将网络序列转换为主机序列
             uint16_t clientport =ntohs(peer.sin_port);//客户端 端口号
             std::cout<<clientip<<"-"<<clientport<<"-"<<"get message# "<<buffer<<std::endl;

             //2.将消息发给别人
             sendto(sock_,buffer,strlen(buffer),0,(struct sockaddr*)&peer,sizeof(peer));
             
           }
       }
       ~UdpServer()//析构
       {}
     private:
     int sock_; //文件描述符
     uint16_t port_;//端口号 
   }; 
}

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

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

相关文章

鸿蒙智联再出发,携手伙伴共赢空间智能化,创造无限可能

新空间&#xff0c;再出发&#xff0c;HarmonyOS Connect伙伴峰会完 2023年8月5日&#xff0c;HarmonyOS Connect伙伴峰会在东莞如期举办&#xff0c;峰会以《一起创造无限可能 新空间 再出发》为主题&#xff0c;深度解读了鸿蒙智联商业模式全面升级以来&#xff0c;给伙伴带来…

Qt拖放事件与拖放操作笔记dragEnterEvent,dropEvent

1 介绍 拖放事件主要用于处理MIME数据&#xff0c;该数据是用于在发送电子邮件时&#xff0c;附加多媒体数据&#xff08;即拖拽一个文件放入邮件中&#xff0c;事件文件的上传&#xff09;。 2 示例 a&#xff09;使用简化步骤声明拖放事件成员函数&#xff1a; b&#xff09;…

C#与C/C++交互(1)——需要了解的基础知识

【前言】 C#中用于实现调用C/C的方案是P/Invoke&#xff08;Platform Invoke&#xff09;&#xff0c;让托管代码可以调用库中的函数。类似的功能&#xff0c;JAVA中叫JNI&#xff0c;Python中叫Ctypes。 常见的代码用法如下&#xff1a; [DllImport("Test.dll", E…

IPv6地址分类,EUI-64转换规则

1、可聚合的单全球单播地址Global Unique Address&#xff1a; Aggregate global unicast address&#xff0c;前3位是001&#xff0c;即2000::/3&#xff0c;目前IANA已经将一部分可聚合全球单播进行了专门使用&#xff0c;如&#xff1a;2001::/16用于IPV6互联网&#xff0c;…

流量分析日志查看

一流量分析 buuctf wireshark 从题目出发&#xff0c;既然是上传登录信息&#xff0c;就直接过滤post请求&#xff0c;即搜索 http.request.methodPOST&#xff0c;因为上传用户登录信息使用的一定是http里的post方法 模式过滤 http.request.method “GET” http.request.…

无涯教程-Perl - getpriority函数

描述 此函数返回进程(PRIO_PROCESS),进程组(PRIO_PGRP)或用户(PRIO_USER)的当前优先级。 参数WHICH指定要为PRIO_PROCESS,PRIO_PGRP或PRIO_USER之一设置优先级的实体,WHO是要设置的进程ID或用户ID。 WHO的值为0定义了当前流程,流程组或用户。这会在不支持系统getpriority()函…

Springboot后端通过路径映射获取本机图片资源

项目场景&#xff1a; 项目中对图片的处理与查看是必不可少的&#xff0c;本文将讲解如何通过项目路径来获取到本机电脑的图片资源 如图所示&#xff0c;在我的本机D盘的图片测试文件夹(文件夹名字不要有中文)下有一些图片&#xff0c; 我们要在浏览器上访问到这些图片&#…

RISC-V基础之函数调用(二)栈与寄存器(包含实例)

堆栈是一种后进先出&#xff08;LIFO&#xff09;的队列&#xff0c;用于存储函数调用时的临时数据和现场数据。堆栈指针sp&#xff08;寄存器2&#xff09;是一个普通的RISC-V寄存器&#xff0c;按照惯例&#xff0c;指向堆栈的顶部。堆栈从高地址向低地址增长&#xff0c;即当…

【UE4 RTS】04-Camera Pan

前言 本篇实现了CameraPawn的旋转功能。 效果 步骤 1. 打开项目设置&#xff0c;添加两个操作映射 2. 打开玩家控制器“RTS_PlayerController_BP”&#xff0c;新建一个浮点型变量&#xff0c;命名为“PanSpeed” 在事件图表中添加如下节点 此时运行游戏可以发现当鼠标移动…

WEB集群——负载均衡集群

目录 一、 LVS-DR 群集。 1、LVS-DR工作原理 2、LVS-DR模式的特点 3、部署LVS-DR集群 3.1 配置负载调度器&#xff08;192.168.186.100&#xff09; 3.2 第一台web节点服务器&#xff08;192.168.186.103&#xff09; 3.3 第二台web节点服务器&#xff08;192.168.186.…

Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案

智能联网技术在国内的发展势头迅猛&#xff0c;随着汽车智能化、网联化发展大潮的到来&#xff0c;智能网联汽车逐步成为汽车发展的主要趋势。越来越多整车厂诉求&#xff0c;希望可以提供本土的测量软件&#xff0c;特别是关于ADAS测试。而Softing中国推出的Q-Vision软件不仅可…

f12 CSS网页调试_css样式被划了黑线怎么办

我的问题是这样的 class加上去了,但是样式不生效,此时可能是样式被其他样式覆盖了, 解决方案就是 给颜色后边添加一个!important

Docker的入门与使用

什么是Docker&#xff1f; docker官网 简介与概述 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#x…

RISCV 5 RISC-V调用规则

RISCV 5 RISC-V调用规则 1 Register Convention1.1 Integer Register Convention1.2 Floating-point Register Convention 2. Procedure Calling Convention2.1 Integer Calling Convention2.2 Hardware Floating-point Calling Convention2.3 ILP32E Calling Convention2.4 Na…

【flink】使用flink-web-ui提交作业报错

使用WebUI提交作业出现错误。 错误截图&#xff1a; 弹框信息&#xff1a; Server Response Message: org.apache.flink.runtime.rest.handler.RestHandlerException: Could not execute application.at org.apache.flink.runtime.webmonitor.handlers.JarRunHandler.lambda$h…

webshell免杀项目-Auto-JSPwebshell(五)

Auto-JSPwebshell/jsp免杀/webshell免杀/自动生成 项目地址&#xff1a; https://github.com/G0mini/Bypass 具体使用请参考&#xff1a; https://mp.weixin.qq.com/s/9-__B0MBRSXHla6O0KU7Gg

缓解针对LLM应用程序的存储提示注入攻击

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 LLM提供提示文本&#xff0c;并根据其已训练和访问的所有数据进行响应。为了用有用的上下文补充提示&#xff0c;一些 AI 应用程序捕获来自用户的输入&#xff0c;并在将最终提示发送到 LLM 之前将用户看不…

08. 容器间通信

目录 1、前言 2、容器间通信 2.1、通过IP地址进行通信 2.2、通过DNS Server进行通信 2.3、通过Joined方式通信 3、容器跨节点通信 3.1、通过容器在宿主机上的端口映射实现 3.2、通过Docker Overlay网络实现 4、小结 1、前言 上一篇《07.Docker网络通信模式》我们初步认…

Qt应用开发(基础篇)——时间微调输入框 QDateTimeEdit、QDateEdit、QTimeEdit

一、前言 QAbstractSpinBox是全部微调输入框的父类&#xff0c;这是一种允许用户通过点击上下箭头按钮或输入数字来调整数值的图形用户界面控件&#xff0c;父类提供了当前值text、对齐方式align、只读readOnly等通用属性和方法。在上一篇数值微调输入框中有详细介绍。 QDateTi…

24届近5年南京航空航天大学自动化考研院校分析

今天给大家带来的是南京航空航天大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京航空航天大学 学校简介 南京航空航天大学创建于1952年10月&#xff0c;是新中国自己创办的第一批航空高等院校之一。1978年被国务院确定为全国重点大学&#xff1b;1981年经…