Linux系统编程,使用C语言实现简单的FTP(服务器/客户端)

2023-05-16

前言

跟着上官社长 陈哥花了一个月的时间终于把Linux系统编程学的差不多了,这一个月真的是头疼啊,各种bug,调的真心心累,不过好在问题都解决掉了,在此也感谢一下答疑老师,给我提供了很多的思路,本文章是对前段时间学习Linux,做一个小小的总结,才疏学浅,只学到这个地步,下来继续努力,加油!。

一.基本功能

  1. get + xxx 从服务器获取某个文件到客户端。

  1. put + xxx 把客户端的某个文件上传到服务器。

  1. cd + 路径 切换目录

  1. lls 列出本地文件列表

  1. ls 列出服务端文件列表

  1. lcd +路径 切换本地目录

二.实现思路

1.使用socket先把服务器和客户端建立连接

2.建立连接后开始信息的交互

客户端输入指令服务器处理指令

三.具体代码如下

先建立socket连接,如下是服务器的代码。

int main(int argc,char**argv)
{
    if(argc !=3 )//判断参数是否输入正确
    {
        printf("input errror\n");    
        exit(-1);
    }
    int s_fd = socket(AF_INET,SOCK_STREAM,0);//创建网络套接字

    struct sockaddr_in addr;
    struct sockaddr_in addr2;
    
     memset(&addr,0,sizeof(struct sockaddr_in));
     memset(&addr2,0,sizeof(struct sockaddr_in));
    int n_read;
    addr.sin_family = AF_INET;//地址协议族
    addr.sin_prot = htons(atoi(argv[2]));//端口号,先使用atoi函数把参数转换成整型,在使用htons转为网络字节序。
    inet_aton(argv[1], &s_addr.sin_addr);//IP地址,使用inet_aton函数把点分十进制的IP地址,转换为网络字节序。例如,192.168.147.155.
    bind(s_fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in));

    listen(s_fd,10);//监听

    int sz = sizeof(struct sockaddr_in);
    while(1)//循环卡住不让退出去。
    {
        int c_fd = accept(s_fd,(struct sockaddr *)&addr2,&sz);//尝试连接
        if(c_fd == -1)
        {
            perror("accept");
            exit(-1);    
        }
        printf("get connect : %s\n",inet_nota(addr2.sin_addr));//连接成功打印对方的IP地址。
      
    }
        return 0;
    }

客服端代码,如下

int main(int argc,char **argv)
{
    int c_fd;
    struct Msg msg;

    struct sockaddr_in c_addr;
    memset(&c_addr,0,sizeof(struct sockaddr));

    // 1. socket
    c_fd = socket(AF_INET,SOCK_STREAM,0);
    if(c_fd==-1)
    {
        perror("socket:");
        exit(-1);
    }
    c_addr.sin_family = AF_INET;
    c_addr.sin_port =htons(atoi(argv[2]));
    inet_aton(argv[1], &c_addr.sin_addr);
    connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr_in));//请求连接
    printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));//连接成功打印IP
    while(1)
    {
    }
    return 0;
}

上面只是服务器和客户端,建立连接的代码,还不携带参数,下面开始客户端和服务器进行通讯。

四.服务器/客户端通讯

1.服务器和客户端共有的文件

#include<stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include <unistd.h>
#include <fcntl.h>

#define LS   0
#define PWD  1
#define GET  2
#define IFGO 3
#define CD   4
#define PUT  5
#define LLS  6
#define LCD  7
#define LPWD 8
#define QUIT 9
#define DOFILE 10

struct Msg
{
        int type;
        char data[1024];
        char buf[128];
};

2.客户端


int get_cmd_type(char *cmd)
{
     //比较输入的指令,找到对应的就返回相对应的指令。
     if(!strcmp("ls",cmd))      return LS;
     if(!strcmp("lls",cmd))     return LLS;
     if(!strcmp("pwd",cmd))     return PWD;
     if(!strcmp("quit",cmd))    return QUIE;
      //在输入的指令字符串里面找,对应的指令
      if(strstr(cmd."cd"))       return CD;
      if(strstr(cmd,"get"))      return GET;
      if(strstr(cmd,"put"))      return PUT;

       return -1;//未找到返回错误
}




char *getdir(char *cms)//分割指令,来获取参数
{
    char *p = NULL;
     p = strtok(cms," ");
     p = strtok(NULL," ");
    return p;
}



int cmd_handler(struct Msg msg,int fd)
{
    int ret;
    char buf[100];//临时空间
    char *dir = NULL;
    int filefd; //文件表示符
    ret = get_cmd_type(msg.data);//输入的指令转换成整数
    switch(ret)//根据ret的值来选择
    {
        case PWD:
        case LS:
        case CD:
                msg.type = 0;//标记符
                write(fd,msg.data,sizeof(msg));//发送命令
                break;
       
        case GET:
                msg.type = 2;
                write(fd,msg.data,sizeof(msg));//发送命令
                break;
        case PUT:
                strcpy(buf,msg.data);
                dir = getdir(buf);
                if(access(dir,F_OK) == -1)//判断参数文件是否存在
                 {    
                        printf("%s not exsit\n",dir);
                  }
                  else//如果存在
                  {
                        filefd = open(dir,O_RDWR);//打开这个文件
                        read(filefd,msg.buf,sizeof(msg.buf));//读取这个文件
                        close(filefd);//关闭这个文件
        
                        write(fd,msg,data,sizeof(msg));//向服务器发送命令
                   }
                
         case QUIT:
                   strcpy(msg.data,"quit");
                   write(fd,msg.data,sizeof(msg));
                   close(fd);//关闭文件
                   exit(-1);//退出程序
         case LLS:
                   system("ls");
                   break;
         case LCD:
                    dir = getdir(msg.data);
                    chdir(dir);
                    break;
    }
    return ret;
}


void hand_sever_message(int c_fd,struct Msg msg)
{
    struct Msg msgget;
    char *dir = NULL;
    int n_read;
    n_read = read(c_fd,&msgget,sizeof(msgget));//客户端执行到这里时,会阻塞在这,等待服务器写入数据
    if(n_read == -1)
    {
        printf("server out \n");
        exit(-1);    
    }
    else if(msg.type == DOFILE)
     {
        dir = getdir(msg.data);
        int filefd = open(dir,O_RDWR|O_CREAT,0666);
         write(filefd,msgget.data,strlen(msgget.data));
        putchar('>');
        fflush(stdout);
     }
    else
    {
        printf("============================\n");
        printf("\n%s\n",msgget.data);
        printf("=============================\n");
        putchar('>');
        fflush(stdout);
    }
}



int main(int argc,char **argv)
{
    int c_fd;
    int ret;
    struct Msg msg;//定义结构体
    struct sockaddr_in c_addr;
    memset(&c_addr,0,sizeof(struct sockaddr));//初始化结构体里的内容

    
    c_fd = socket(AF_INET,SOCK_STREAM,0);//创建socket
    if(c_fd==-1)
    {
        perror("socket:");
        exit(-1);
    }
    c_addr.sin_family = AF_INET;
    c_addr.sin_port =htons(atoi(argv[2]));
    inet_aton(argv[1], &c_addr.sin_addr);

    connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr_in));//请求连接
    printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));//连接成功打印IP
    while(1)
    {
        memset(msg.data,0,sizeof(msg.data));
        scanf("%[\n]",msg.data);//获取客户端指令
        if(strlen(msg.data) == 0)
        {
            if(mark == 1)
            {
                printf(">");
            }
        }
        ret = cmd_handler(msg,c_fd);//封装一个函数,处理指令
        
        if(ret >IFGO)
        {
            putchar('>');
            fflush(stdout);
            continue;
        }
        if(ret == -1)
        {
            printf("commend out\n");
            printf(">");
            fflush(stdout);
        }
        handler_sever_message(c_fd,msg);//处理客户端返回内容 
    }
    close(c_fd);//关闭文件
    return 0;
}

3.服务器


int get_cmd_type(char *cmd)//把指令转换成整型
{
    if(!strcmp("ls",cmd))  return LS;
    if(!strcmp("quit",cmd)) return QUIT;
    if(!strcmp("pwd",cmd))  return PWD;
    if(strstr(cmd,"cd")!=NULL)  return CD;
    if(strstr(cmd,"get")!=NULL) return GET;
    if(strstr(cmd,"put")!=NULL) return PUT;
    return -1;
}

char *getdir(char cmd)//分割指令,获取第二个参数
{
    char *p = NULL;
    p = strtok(cmd," ");
    p = strtok(NULL," ");
    return p;
}


void msg_handler(struct Msg msg,int fd)
{
    int ret;
     char *dir;
    char *databuf[1024] = {0};//临时空间
    int fdfile;//文件描述符
    ret = get_cmd_type(msg.data);

    switch(ret)
            case LS:
            case PWD:
                    msg.type = 0
                    FILE *r = popen(msg.data,"r");执行该参数,并读取,返回读取文件的指针
                    fread(msg.data,sizeof(msg.data),1,r);读取到data空间里面,读取一次,读取的文件是上面r指向的文件。
                    write(fd,msg.data,sizeof(msg));读取完成后写入。
                    break;
            case CD:
                   dir = getdir(msg.data);//先把指令分割出来,获取参数
                    printf("dir :%s\n",dir);//打印参数
                    chdir(dir); 将当前目录改向参数指向的目录。
                    break;
            case GET:
                    dir = getdir(msg.data);//获取参数文件
                    if(access(dir,F_OK)== -1)//判断文件存在吗
                     {
                            strcpy(msg.data,"NO this file");
                      }
                      else//如果存在
                       {
                            msg.type = DOFILE; //标记
                            fdfile = open(dir,O_RDWR);//打开此文件
                            read(fdfile,databuf,sizeof(databuf));//读取此文件到临时空间databuf里面
                            close(fdfile);//读取完成,关闭此文件
                            strcpy(msg.data,databuf);//将databuf拷贝
                            write(fd,msg.data,sizeof(msg));//写入
                       }
                    break;

            case PUT:
                    dir = getdir(msg.data);//分割获取第二个参数
                   fdfile =  open(dir,O_RDWR|O_CREAT,0666);//打开该参数的文件
                    write(fd,msg.buf,strlen(msg.buf));//将客户端读取的内容写入服务器
                    close(fdfile);//写完关闭文件
                    break;
            case QUIT:
                    printf("client quit\n");//打印退出信心
                    exit(-1);//退出程序

}
int main(int argc,char**argv)
{
    if(argc !=3 )//判断参数是否输入正确
    {
        printf("input errror\n");    
        exit(-1);
    }
    int s_fd = socket(AF_INET,SOCK_STREAM,0);//创建网络套接字
    struct Msg msg;
    struct sockaddr_in addr;
    struct sockaddr_in addr2;
    
     memset(&addr,0,sizeof(struct sockaddr_in));
     memset(&addr2,0,sizeof(struct sockaddr_in));
    int n_read;
    addr.sin_family = AF_INET;//地址协议族
    addr.sin_prot = htons(atoi(argv[2]));//端口号,先使用atoi函数把参数转换成整型,在使用htons转为网络字节序。
    inet_aton(argv[1], &s_addr.sin_addr);//IP地址,使用inet_aton函数把点分十进制的IP地址,转换为网络字节序。例如,192.168.147.155.
    bind(s_fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in));

    listen(s_fd,10);//监听

    int sz = sizeof(struct sockaddr_in);
    while(1)//循环卡住不让退出去。
    {
        int c_fd = accept(s_fd,(struct sockaddr *)&addr2,&sz);//尝试连接
        if(c_fd == -1)
        {
            perror("accept");
            exit(-1);    
        }
        printf("get connect : %s\n",inet_nota(addr2.sin_addr));//连接成功打印对方的IP地址。
        if(fork()== 0)//创建子进程来对接,进行通讯
        {
                memset(msg.data,0,sizeof(msg.date));
                n_read =read(c_fd,&msg,sizeof(msg));//读取客户端发过来的消息
                if(n_read == 0)//判断读取信息
                {
                    printf("client out\n");
                    break;
                }else (if n_read>0)//如果读取到了
                {
                msg_hanfler(msg,c_fd);//处理函数
                }
        }
      
    }
        return 0;
}

以上就是我对这段时间学习Linux的理解,希望可以帮助到大家谢谢

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux系统编程,使用C语言实现简单的FTP(服务器/客户端) 的相关文章

  • 反向散射耦合RFID系统的原理及特点,带你更深入的了解

    一 反向散射耦合RFID系统 1 反向散射 雷达技术为RFID的反向散射耦合方式提供了理论和应用基础 当电磁波遇到空间目标时 xff0c 其能量的一部分被目标吸收 xff0c 另一部分以不同的强度散射到各个方向 在散射的能量中 xff0c
  • 西门子PLC,1200PLC如何接线,2分钟就能明白

    西门子PLC xff0c 1200PLC如何接线 xff0c 2分钟就能明白 西门子PLC xff0c 1200PLC如何接线 xff0c 2分钟就能明白 哔哩哔哩 bilibili
  • 2022年嵌入式开发就业前景怎么样?

    时间 xff1a 2022年5月26号 xff01 这几年嵌入式开发的发展前景可以说是非常的香 xff01 从工资和找工作的难易程度上说都是 xff01 按老师傅的说法就是 xff1a 加班不严重 xff0c 注重积累 xff0c 越往底层
  • ARM结构体系3:ARM指令的寻址和异常中断处理

    目录 ARM处理器的八种寻址方式 1 立即数寻址 2 寄存器寻址 3 寄存器间接寻址 4 寄存器移位寻址 5 基址变址寻址 6 多寄存器寻址 7 相对寻址 8 堆栈寻址 9 GNU汇编伪指令 异常中断处理 1 7种异常源 2 异常向量表 A
  • 51单片机(ESP8266模块)

    前言 xff1a 蓝牙 xff0c ESP 01s xff0c Zigbee NB Iot等通信模块都是基于AT指令的设计 一 AT指令 AT指令集是从终端设备 xff08 Terminal Equipment xff0c TE 或数据终端
  • 嵌入式工作机会会越来越少吗

    我认为嵌入式工作会越来越多 在当前产业结构升级的大背景下 xff0c 物联网会与诸多的行业领域产生更加紧密的联系 xff0c 而这个过程必然离不开嵌入式开发的参与 应用场景对于嵌入式开发领域的发展有非常直接的影响 xff0c 嵌入式开发要想
  • 大学生为何很想往嵌入式方向发展?

    这几年嵌入式工资一直在再涨 xff0c 挺好的 xff01 可以选择的公司也比较多 xff0c 起薪差不读在10k 13k的样子 招聘公司统计的数据是19K 优点1 xff1a 应届生嵌入式行业的薪资在毕业生眼里看来真的是很香 xff0c
  • 涨姿势 | 一文说透电机控制器硬件在环测试(MCU HIL)

    软件质量是嵌入式产品开发中最关注的问题之一 随着产品迭代 xff0c 软件复杂程度越来越高 xff0c 为保证软件质量 xff0c 需要对软件进行大量的测试 xff0c 这会在整个产品周期中消耗大量时间及资源 另一方面 xff0c 市场竞争
  • VMware Workstation创建Windows 11(21H2)虚拟机

    2021年6月24日 xff0c 微软发布了Windows 11 xff0c 很多人都想 尝尝鲜 可以为较高的电脑配置 xff0c 使得很多老电脑 望而却步 xff0c 或者有人想换可又嫌麻烦或不舍得 所以今天我来带大家创建Windows
  • 计算机知识——常见的存储类型

    一 常见存储器类型 xff1a 1 易失 非易失性存储器 xff1a 是指存储器断电后 xff0c 它存储的数据内容是否会丢失的特性 由于一般易失性存储器存取速度快 xff0c 而非易失性存储器可长期保存数据 易失性存储器最典型的代表是内存
  • 使用select函数实现TCP并发服务器

    首先介绍一下select 函数的功能 参数 返回值 int select int nfds fd set readfds fd set writefds fd set exceptfds struct timeval timeout voi
  • ROS下gazebo打不开,最新最全的可行方法

    问题具体描述 xff1a 在打开roscore的情况下 执行命令行 xff1a rosrun gazebo ros gazebo 或者命令行 xff1a roslaunch gazebo ros empty world launch 但是只
  • 西门子S7-200SMART模拟量输入、输出模块接线

    西门子S7 200SMART模拟量输入 输出模块接线 https www bilibili com video BV1J3411R7nu spm id from 61 333 337 search card all click 西门子S7
  • SyntaxError: Non-ASCII character ‘\xe9‘报错

    本人在用vscode写python代码时 xff0c 第一次运行就遇到了这种情况 解决方法 xff1a 在python文件开头加上以下一行 xff1a coding utf 8 如下图所示 xff1a 即可解决报错问题 xff08 注意 x
  • 最新:ubuntu18.04下,vscode报错:No such file or directory

    我遇到的问题是 xff1a 在vscode编译下是没有报错的 xff0c 但是运行文件时 xff0c 还是报错了 如下图所示 xff1a 实际上 xff0c vscode会经常遇到这种类似的问题 xff0c 建议可以使用ubuntu的终端运
  • 打开了ros中的rviz,显示不了机器人模型

    问题 xff1a 可以打开gazebo xff0c 但是打开rviz后 xff0c 显示不了机器人模型 报错情况如下图所示 xff1a 解决 xff1a 看看自己的launch文件是否加了以下的节点 xff1a lt node pkg 61
  • 在vscode的界面的竖线光标变成灰色方块,怎么解决?(最全方法集合)

    具体情况如下图所示 xff1a 原因 xff1a 是vscode安装了vim xff0c 所以会出现这种情况 解决方法 xff1a 1 点一下insert键 xff0c 可以单次取消灰色方块的出现 xff0c 但是不能根除灰色方块 2 卸载
  • 给keil5加芯片包(PACK)

    按照这个链接来安装即可 xff0c 非常的详细和简单 https blog csdn net qq 45931949 article details 125219598
  • Invoking “make -j1“ failed

    Invoking 34 make j1 34 failed 在进行catkin make j1 的单线程编译时 xff0c 出现了很玄学的问题 xff0c 就是一会编译成功 xff0c 之后重新编译又报这个错误 xff0c 终端报错的是这个
  • find a package configuration file provided by “GeographicLib“, but CMake did not find one.

    在编译kitty数据集时 xff0c 编译不通过 xff0c 发现是安装的系统没有安装GeographicLib库 xff0c 所以报错了 xff0c 解决方法就是自己安装就可以了 xff0c 命令行如下 xff1a git clone h

随机推荐

  • fatal error: glog/logging.h: 没有那个文件或目录

    compilation terminated lidar localization CMakeFiles hello kitti node dir build make 206 recipe for target 39 lidar loca
  • Docker

    概念 Go语言开发 xff0c 开发者打包他们的应用以及依赖包到一个轻量级 可移植的容器中 xff0c 然后发布到任何流行的 Linux 机器上 xff0c 也可以实现虚拟化 容器是完全使用沙箱机制 xff0c 相互之间不会有任何接口 xf
  • 【毕设项目】 基于stm32的四轴飞行器设计 - 物联网 嵌入式 单片机

    1 简介 Hi xff0c 大家好 xff0c 这里是丹成学长 xff0c 今天向大家介绍一个学长做的单片机项目 基于stm32的四轴飞行器设计 大家可用于 课程设计 或 毕业设计 单片机 嵌入式毕设选题大全及项目分享 https blog
  • keil5的安装详解(看完必会,不会你打我)

    如何安装KEIL5 本内容所涉及的软件只供教学使用 xff0c 不得用于商业用途 个人或公司因商业用途导致的法律责任 xff0c 后果自负 温馨提示 1 安装路径不能带中文 xff0c 必须是英文路径 2 安装目录不能跟51的KEIL或者K
  • 【毕设选题推荐】机器人工程专业毕设选题推荐

    文章目录 1前言2 如何选题3 机器人工程 毕设 选题推荐4 最后 1前言 x1f947 近期不少学弟学妹询问学长关于机器人工程专业工程专业相关的毕设选题 xff0c 学长特意写下这篇文章以作回应 xff01 以下是学长亲手整理相关的毕业设
  • 【开源】千元级桌面六轴机械臂,适合教育科研二次开发

    目前市场上面的机械臂大多数在10万元左右 xff0c 由于成本太高 xff0c 不能广泛应用 xff0c 只能应用于一些特殊要求的工业场合 那么有没有一款机械臂小巧灵活 xff0c 价格接地气 xff1f myCobot 280 amp n
  • 基于主成分分析的LSTM和GPR模型融合负荷预测(可实现概率预测)

    基于主成分分析的LSTM和GPR融合负荷预测 一 背景介绍 二 部分代码展示 三 结果分析 一 背景介绍 本文数据来源于某地区2020年1月1日至12月31日的综合能源系统冷热电负荷和其他各种影响因子 xff0c 每间隔一小时采一次样 本文
  • Qt制作图表生成器

    基于Qt中的QCharts模块制作图表生成器软件 添加模块 QT 43 61 charts 添加命名空间 using namespace QtCharts 该软件可制作多种图表 多样化主题设置 保存移植便捷快速 输入相关数据 自动生成对应图
  • opencv简易数字识别

    前言 使用opencv xff0c 进行简单的数字识别 注意 xff1a 此案例中的数字识别仅当做学习参考 xff0c 想要真正实现数字识别 xff0c 实际情况复杂很多 思路 图片预处理 xff0c 将图片转灰度后再二值化 xff0c 使
  • Java并发:五种线程安全类型、线程安全的实现、枚举类型

    1 Java中的线程安全 Java线程安全 xff1a 狭义地认为是多线程之间共享数据的访问 Java语言中各种操作共享的数据有5种类型 xff1a 不可变 绝对线程安全 相对线程安全 线程兼容 线程独立 不可变 不可变 xff08 Imm
  • 万字长文!用代码实例带你彻底:精通CompletableFuture的使用

    前言 创建线程的方式只有两种 xff1a 继承Thread或者实现Runnable接口 但是这两种方法都存在一个缺陷 xff0c 没有返回值 Java 1 5 以后 xff0c 可以通过向线程池提交一个Callable来获取一个包含返回值的
  • 阿里专家推荐2023面试必看的《Java面试手册》,让你offer拿到手软

    前言 本文是为了帮大家快速回顾了Java中知识点 xff0c 这套面试手册涵盖了诸多Java技术栈的面试题和答案 xff0c 相信可以帮助大家在最短的时间内用作面试复习 xff0c 能达到事半功倍效果 本来想将文件上传到github上 xf
  • Java 枚举实现单例模式,线程安全又优雅!

    1 双重校验锁单例 xff08 DCL xff09 public class Singleton private static volatile Singleton singleton private Singleton public st
  • ROS系统下gazebo环境中,无人机结合目标跟踪算法(SiamCar),完成对物体的跟踪(可以是小车或者其他的

    ROS系统下gazebo环境中 xff0c 无人机结合目标跟踪算法 xff08 SiamCar xff09 xff0c 完成对物体的跟踪 xff08 可以是小车或者其他的 xff09 xff0c 然后给出轨迹对比图等评估指标 开发语言 xf
  • Linux实验---多文件编程Makefile实验二

    多文件编程Makefile实验指导书 一 实验题目 xff1a 二 实验目的三 实验内容四 实验步骤五 实验结果六 总结 一 实验题目 xff1a 多文件编程Makefile 二 实验目的 xff08 1 熟悉Linux开发环境 xff08
  • C语言 | NowCoder链表题解

    目录 前言1 单向链表2 链表交换3 单链表求和4 双链表求和5 链表删除6 链表添加结点7 反转链表 前言 题目来源于 https www nowcoder com exam oj page 61 1 1 单向链表 描述 从键盘输入一个长
  • Github | 如何在Github上只下载一个文件或文件夹!?

    1 写在前面 用过github的小伙伴们都知道 xff0c 我们可以通过git clone命令来下载整个项目到本地 x1f618 但我最近在使用github的时候遇到一个问题 xff0c 就是我只想下载这一个文件 xff0c 其他的我都不想
  • 远程登陆协议SSH和talnet

    SSH和talnet是远程登陆协议 这两种协议都是基于客户端和服务器的思想 1 SSH secure shell外壳保护协议 是建立在应用层和传输层上的安全协议 xff0c 可以有效防止远程管理过程中的信息泄露问题 xff0c 默认端口是2
  • Integer与int的区别

    1 Integer是int的包装类 xff0c int则是java的一种基本数据类型 2 Integer变量必须实例化才能使用 xff0c int变量不需要实例化 3 Integer的默认值是null xff0c 而int的默认值是0 4
  • Linux系统编程,使用C语言实现简单的FTP(服务器/客户端)

    前言 跟着上官社长 陈哥花了一个月的时间终于把Linux系统编程学的差不多了 xff0c 这一个月真的是头疼啊 xff0c 各种bug xff0c 调的真心心累 xff0c 不过好在问题都解决掉了 xff0c 在此也感谢一下答疑老师 xff