Linux基础网络编程-Socket通信

news/2024/9/17 7:53:07/ 标签: linux, 网络, 运维

本文使用C语言,在Centos实现Socket两种通信类型(TCP和UDP)

文章目录

  • 一、安装gcc
  • 二、使用TCP协议,实现Socket(SOCKE_STREAM)流式通信
    • 1. 编写`TCP_server.c`
      • 函数和参数解释
    • 2.编写`TCP_client.c`
      • 函数和参数解释
    • 3. 编译并运行上述两个文件
      • 3.1 编译
      • 3.2 运行(启动两个终端,分别运行)
      • 测试
  • 三、使用数据报协议UDP,实现数据报socket(SOCK_DGRAM)通信
    • 1. 编写`UDP_server.c`
      • 函数和参数解释
    • 2.编写`UDP_client.c`
      • 函数和参数解释
    • 3.编译运行及测试,参考TCP即可

一、安装gcc

如果Centos没有C语言编译器,使用下面命令进行下载安装

yum -y install gcc

使用下列命令查看安装版本

gcc --version

如安装失败,请寻找其他教程

二、使用TCP协议,实现Socket(SOCKE_STREAM)流式通信

1. 编写TCP_server.c

#include <sys/types.h>  // 包含基本系统数据类型
#include <sys/socket.h> // 包含socket函数及数据结构
#include <netinet/in.h> // 定义数据结构sockaddr_in
#include <arpa/inet.h>  // 提供IP地址转换函数
#include <string.h>     // 提供字符串处理函数
#include <stdlib.h>     // 提供通用工具函数
#include <stdio.h>      // 提供输入输出函数
#include <unistd.h>     // 提供对POSIX操作系统API的访问功能#define QUEUE 20        // 最大同时连接请求数
#define BUFFER_SIZE 1024 // 缓冲区大小int main()
{// 创建socket,指定IPv4协议族,流式socketint server_sockfd = socket(AF_INET, SOCK_STREAM, 0);// 定义服务器地址结构struct sockaddr_in server_sockaddr;server_sockaddr.sin_family = AF_INET; // 地址族server_sockaddr.sin_port = htons(8887); // 端口号,使用htons进行字节序转换server_sockaddr.sin_addr.s_addr = inet_addr("192.168.138.133"); // 服务器IP地址// 绑定socketif(bind(server_sockfd, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr)) == -1){perror("bind"); // 如果绑定失败,打印错误信息exit(1); // 退出程序}// 监听网络连接if(listen(server_sockfd, QUEUE) == -1){perror("listen"); // 如果监听失败,打印错误信息exit(1); // 退出程序}// 定义客户端地址结构char buffer[BUFFER_SIZE];struct sockaddr_in client_addr;socklen_t length = sizeof(client_addr);// 接受客户端连接int conn = accept(server_sockfd, (struct sockaddr *)&client_addr, &length);if(conn < 0){perror("connect"); // 如果连接失败,打印错误信息exit(1); // 退出程序}// 数据交换循环while(1){memset(buffer, 0, sizeof(buffer)); // 清空缓冲区int len = recv(conn, buffer, sizeof(buffer), 0); // 接收数据if(strcmp(buffer, "exit\n") == 0) // 如果接收到"exit"命令,则退出循环break;fputs(buffer,{"code":504,"success":false,"message":"Gateway timeout has occurred"} stdout); // 将接收到的数据打印到标准输出send(conn, buffer, len, 0); // 将接收到的数据发送回客户端}// 关闭连接close(conn);close(server_sockfd);return 0;
}

函数和参数解释

  • socket(int domain, int type, int protocol): 创建一个新的socket。

    • domain: 指定协议族,这里是AF_INET(IPv4网络协议)。
    • type: 指定socket类型,这里是SOCK_STREAM(提供顺序化、可靠、双向的基于连接的字节流)。
    • protocol: 指定具体协议,0表示自动选择type对应的默认协议,这里是TCP。
  • bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 将socket绑定到本地地址。

    • sockfd: socket文件描述符。
    • addr: 指向本地地址信息的指针。
    • addrlen: 地址信息的长度。
  • listen(int sockfd, int backlog): 开始监听网络连接请求。

    • sockfd: socket文件描述符。
    • backlog: 最大同时连接请求数。
  • accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen): 接受一个连接请求。

    • sockfd: socket文件描述符。
    • addr: 指向客户端地址信息的指针。
    • addrlen: 地址信息的长度。
  • recv(int sockfd, void *buf, size_t len, int flags): 接收数据。

    • sockfd: 连接的socket文件描述符。
    • buf: 指向接收缓冲区的指针。
    • len: 缓冲区的长度。
    • flags: 传输控制标志,这里为0表示无特殊操作。
  • send(int sockfd, const void *buf, size_t len, int flags): 发送数据。

    • sockfd: 连接的socket文件描述符。
    • buf: 指向数据缓冲区的指针。
    • len: 要发送的数据字节数。
    • flags: 传输控制标志,这里为0表示无特殊操作。

这段代码首先创建一个服务器端的socket,然后绑定到本地地址和端口上,之后监听来自客户端的连接请求。一旦接受到连接请求,服务器就会进入一个循环,接收客户端发送的数据并将其回显给客户端,直到接收到"exit"命令为止。最后,关闭客户端和服务器的socket连接。

2.编写TCP_client.c

#include <sys/types.h>  // 包含基本系统数据类型
#include <sys/socket.h> // 包含socket函数及数据结构
#include <netinet/in.h> // 定义数据结构sockaddr_in
#include <arpa/inet.h>  // 提供IP地址转换函数
#include <string.h>     // 提供字符串处理函数
#include <stdlib.h>     // 提供通用工具函数
#include <stdio.h>      // 提供输入输出函数
#include <unistd.h>     // 提供对POSIX操作系统API的访问功能#define QUEUE 20        // 最大同时连接请求数
#define BUFFER_SIZE 1024 // 缓冲区大小int main()
{// 创建socket,指定IPv4协议族,流式socketint sock_cli = socket(AF_INET, SOCK_STREAM, 0);// 定义服务器地址结构struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr)); // 初始化地址结构servaddr.sin_family = AF_INET; // 地址族servaddr.sin_port = htons(8887); // 端口号,使用htons进行字节序转换servaddr.sin_addr.s_addr = inet_addr("192.168.138.133"); // 服务器IP地址// 连接服务器if(connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){perror("connect"); // 如果连接失败,打印错误信息exit(1); // 退出程序}char sendbuf[BUFFER_SIZE]; // 发送缓冲区char recvbuf[BUFFER_SIZE]; // 接收缓冲区// 数据交换循环while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){send(sock_cli, sendbuf, strlen(sendbuf), 0); // 发送数据if(strcmp(sendbuf, "exit\n") == 0) // 如果输入"exit"命令,则退出循环break;recv(sock_cli, recvbuf, sizeof(recvbuf), 0); // 接收数据fputs(recvbuf, stdout); // 将接收到的数据打印到标准输出memset(sendbuf, 0, sizeof(sendbuf)); // 清空发送缓冲区memset(recvbuf, 0, sizeof(recvbuf)); // 清空接收缓冲区}// 关闭socketclose(sock_cli);return 0;
}

函数和参数解释

  • socket(int domain, int type, int protocol): 创建一个新的socket。

    • domain: 指定协议族,这里是AF_INET(IPv4网络协议)。
    • type: 指定socket类型,这里是SOCK_STREAM(提供顺序化、可靠、双向的基于连接的字节流)。
    • protocol: 指定具体协议,0表示自动选择type对应的默认协议,这里是TCP。
  • connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 请求连接到指定的socket。

    • sockfd: socket文件描述符。
    • addr: 指向目标主机地址信息的指针。
    • addrlen: 地址信息的长度。
  • send(int sockfd, const void *buf, size_t len, int flags): 发送数据。

    • sockfd: socket文件描述符。
    • buf: 指向数据缓冲区的指针。
    • len: 要发送的数据字节数。
    • flags: 传输控制标志,这里为0表示无特殊操作。
  • recv(int sockfd, void *buf, size_t len, int flags): 接收数据。

    • sockfd: socket文件描述符。
    • buf: 指向接收缓冲区的指针。
    • len: 缓冲区的长度。
    • flags: 传输控制标志,这里为0表示无特殊操作。

这段代码首先创建一个客户端的socket,然后连接到服务器的指定IP地址和端口上。一旦连接成功,客户端就会进入一个循环,从标准输入读取数据发送到服务器,并接收服务器的回应,直到输入"exit"命令为止。最后,关闭socket连接。

3. 编译并运行上述两个文件

3.1 编译

gcc TCP_server.c -o TCP_server
gcc TCP_client.c -o TCP_client

3.2 运行(启动两个终端,分别运行)

./TCP_server
./TCP_client

启动成功后,如图所示:
在这里插入图片描述

测试

在client端输入test
在这里插入图片描述
按下回车,可以看到,server端收到test
在这里插入图片描述

三、使用数据报协议UDP,实现数据报socket(SOCK_DGRAM)通信

1. 编写UDP_server.c

#include <sys/types.h> // 包含系统数据类型定义
#include <sys/socket.h> // 提供socket函数及相关数据结构
#include <netinet/in.h> // 包含IP地址和端口号数据结构
#include <arpa/inet.h> // 提供IP地址转换函数
#include <string.h> // 提供字符串处理函数
#include <stdlib.h> // 提供标准库函数
#include <sys/shm.h> // 提供共享内存相关函数
#include <stdio.h> // 提供输入输出函数
#include <fcntl.h> // 提供文件控制函数
#include <unistd.h> // 提供POSIX操作系统API#define RECVLENTH 120 // 定义接收数据长度
#define SENDLENTH 120 // 定义发送数据长度int main(int argc, char **argv)
{int sockefd = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个UDP socketif(sockefd == -1){perror("socket failed!"); // 输出错误信息}struct sockaddr_in saddr, caddr; // 定义服务器地址结构和客户端地址结构memset(&saddr, 0, sizeof(struct sockaddr_in)); // 初始化服务器地址结构saddr.sin_family = AF_INET; // 设置地址族为IPv4saddr.sin_port = htons(6666); // 设置端口号,使用htons进行字节序转换saddr.sin_addr.s_addr = inet_addr("192.168.138.133"); // 设置服务器IP地址int ret = bind(sockefd, (struct sockaddr*)&saddr, sizeof(struct sockaddr)); // 将socket绑定到服务器地址if(ret == -1){perror("bind failed!"); // 输出错误信息}char buf[RECVLENTH]; // 定义接收数据的缓冲区memset(buf, 0, RECVLENTH); // 初始化接收缓冲区int size = sizeof(struct sockaddr); // 获取地址结构的长度recvfrom(sockefd, buf, RECVLENTH, 0, (struct sockaddr*)&caddr, &size); // 接收客户端发送的数据printf("[server recv]:%s\n", buf); // 打印接收到的数据char buf1[SENDLENTH] = {"hello client!"}; // 准备要发送的数据sendto(sockefd, buf1, strlen(buf1), 0, (struct sockaddr*)&caddr, sizeof(struct sockaddr)); // 发送数据给客户端close(sockefd); // 关闭socket连接return 0;
}

函数和参数解释

  • socket(AF_INET, SOCK_DGRAM, 0): 创建一个UDP socket。

    • AF_INET: 指定协议族为IPv4。
    • SOCK_DGRAM: 指定socket类型为数据报套接字,即UDP。
    • 0: 传输协议,这里为默认值。
  • bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 将socket绑定到特定地址。

    • sockfd: socket文件描述符。
    • addr: 指向要绑定的地址结构的指针。
    • addrlen: 地址结构的长度。
  • recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen): 接收数据报。

    • sockfd: socket文件描述符。
    • buf: 接收数据的缓冲区。
    • len: 缓冲区长度。
    • flags: 接收标志,这里为0表示无特殊操作。
    • src_addr: 指向发送方地址结构的指针。
    • addrlen: 地址结构的长度。
  • sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen): 发送数据报。

    • sockfd: socket文件描述符。
    • buf: 要发送的数据。
    • len: 数据长度。
    • flags: 发送标志,这里为0表示无特殊操作。
    • dest_addr: 指向目标地址结构的指针。
    • addrlen: 地址结构的长度。

这段代码创建了一个UDP服务器端,绑定到特定地址和端口上。它接收来自客户端的数据报,然后回显"hello client!"给客户端,并关闭连接。

2.编写UDP_client.c

#include <sys/types.h> // 包含系统数据类型定义
#include <sys/socket.h> // 提供socket函数及相关数据结构
#include <netinet/in.h> // 包含IP地址和端口号数据结构
#include <arpa/inet.h> // 提供IP地址转换函数
#include <string.h> // 提供字符串处理函数
#include <stdlib.h> // 提供标准库函数
#include <sys/shm.h> // 提供共享内存相关函数
#include <stdio.h> // 提供输入输出函数
#include <fcntl.h> // 提供文件控制函数
#include <unistd.h> // 提供POSIX操作系统API#define RECVLENTH 120 // 定义接收数据的缓冲区大小
#define SENDLENTH 120 // 定义发送数据的缓冲区大小int main(int argc, char **argv) // 主函数入口,接收命令行参数
{int sockefd = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个UDP socketif (sockefd == -1) // 检查socket是否创建成功{perror("socket failed!"); // 输出错误信息}struct sockaddr_in saddr, caddr; // 定义服务器地址结构和客户端地址结构memset(&saddr, 0, sizeof(struct sockaddr_in)); // 初始化服务器地址结构saddr.sin_family = AF_INET; // 设置地址族为IPv4saddr.sin_port = htons(6666); // 设置端口号,使用htons进行字节序转换saddr.sin_addr.s_addr = inet_addr("192.168.138.133"); // 设置服务器IP地址char buf[SENDLENTH] = "hello server"; // 准备要发送的数据sendto(sockefd, buf, strlen(buf), 0, (struct sockaddr*)&saddr, sizeof(struct sockaddr)); // 发送数据给服务器char buf1[RECVLENTH]; // 定义接收数据的缓冲区memset(buf1, 0, RECVLENTH); // 初始化接收缓冲区int size = sizeof(struct sockaddr); // 获取地址结构的长度recvfrom(sockefd, buf1, RECVLENTH, 0, (struct sockaddr*)&caddr, &size); // 接收服务器发送的数据printf("[client recv]:%s\n", buf1); // 打印接收到的数据close(sockefd); // 关闭socket连接return 0; // 返回程序执行成功
}

函数和参数解释

  • socket(AF_INET, SOCK_DGRAM, 0): 创建一个UDP socket。

    • AF_INET: 指定协议族为IPv4。
    • SOCK_DGRAM: 指定socket类型为数据报套接字,即UDP。
    • 0: 传输协议,这里为默认值。
  • bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 将socket绑定到特定地址。

    • sockfd: socket文件描述符。
    • addr: 指向要绑定的地址结构的指针。
    • addrlen: 地址结构的长度。
  • recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen): 接收数据报。

    • sockfd: socket文件描述符。
    • buf: 接收数据的缓冲区。
    • len: 缓冲区长度。
    • flags: 接收标志,这里为0表示无特殊操作。
    • src_addr: 指向发送方地址结构的指针。
    • addrlen: 地址结构的长度。
  • sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen): 发送数据报。

    • sockfd: socket文件描述符。
    • buf: 要发送的数据。
    • len: 数据长度。
    • flags: 发送标志,这里为0表示无特殊操作。
    • dest_addr: 指向目标地址结构的指针。
    • addrlen: 地址结构的长度。

这段代码创建了一个UDP客户端,向特定地址和端口发送"hello server",然后接收服务器端回复的数据并打印出来。

3.编译运行及测试,参考TCP即可





转载请注明出处
作者:BQ
主页:https://blog.csdn.net/weixin_52677672?type=blog
QQ群:958124241
Learn Together!


http://www.ppmy.cn/news/1521470.html

相关文章

MyBatis的动态SQL---组合条件查询与传递集合和数组(超详细)

MyBatis的动态SQL—组合条件查询与传递集合和数组&#xff08;超详细&#xff09; 文章目录 MyBatis的动态SQL---组合条件查询与传递集合和数组&#xff08;超详细&#xff09;一、 定义二、mybatis提供的几大标签1. if 标签2. choose、when和otherwise标签3. trim标签4. forea…

微信小程序垃圾回收的前景方向

在当今这个环保意识日渐增强的时代&#xff0c;如何有效处理日常生活产生的垃圾已成为亟待解决的社会问题。微信小程序凭借其便捷性和广泛的用户基础&#xff0c;在推广垃圾分类与回收方面展现出巨大潜力。作为一款集智能化分类指导、在线预约回收、环保知识普及于一体的微信小…

OSPFV3 华为

1 OSPFV3简介 (IPV6) 定义 OSPF(Open Shortest Path First)是IETF组织开发的一个基于链路状态的内部网关协议(Interior Gateway Protocol)。 目前针对IPv4协议使用的是OSPF Version 2,针对IPv6协议使用OSPF Version 3。 OSPFv3是OSPF Version 3的简称。OSPFv3是运行于I…

opencv 实现两个图片的拼接去重功能

基础知识介绍 cv::Mat 是OpenCV库中用来表示图像和矩阵数据的核心类之一。它是一个多维数组&#xff0c;可以存储图像像素数据、矩阵数据以及其他类型的数据。以下是关于 cv::Mat 类的一些详细解释&#xff1a; 构造函数&#xff1a;cv::Mat 类有多个构造函数&#xff0c;可以用…

计算机的错误计算(八十四)

摘要 讨论双曲余割函数 csch(x)的计算精度问题。 例1. 计算 csch(320.97) . 不妨在 LibreOffice的电子表格中计算&#xff0c;则有&#xff1a; 若利用 csch(x) 1/sinh(x) 在Java中计算&#xff1a; import java.lang.Math; public class Csch{public static void main(S…

虚幻地形高度图生成及测试

虚幻地形高度图生成及测试 虚幻引擎地形系统将高度数据存储在高度图中&#xff0c;这是一个灰阶图像&#xff0c;使用黑白色值来存储地貌高程。在高度图中&#xff0c;纯黑色值表示最低点&#xff0c;纯白色值表示最高点。支持16位灰阶PNG、8位灰阶r8及16位灰阶r16格式。 本文…

【Linux】gcc/g++ 、make/Makefile、git、gdb 的使用

目录 1. Linux编译器-gcc/g1.1 编译器gcc/g的工作步骤1.2 函数库1.2.1 函数库的作用及分类1.2.2 动态链接和静态链接1.2.3 动态库和静态库的优缺点 1.3 gcc选项 2. Linux项目自动化构建工具-make/Makefile2.1 .PHONY2.2 尝试编写进度条程序 3. git3.1 安装 git3.2 下载项目到本…

51单片机的智能台灯设计【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块DS1302时间模块光敏传感器模块人体红外模块按键等模块构成。适用于智能台灯、自动调节灯光亮度等相似项目。 可实现基本功能: 1、LCD1602实时显示北京时间、环境光照强度、手动/自动模式、台灯亮度等信息&#xff1…

奥威-金蝶云星空BI方案

用金蝶云星空来记账&#xff0c;那确实好&#xff0c;但如果让你再去做一份详细的报表呢&#xff1f;自己开发的话&#xff0c;成本大、耗时长&#xff0c;一旦有了新的需求又要一再开发&#xff0c;长此以往将增加使用者使用难度&#xff0c;降低数据分析对运营决策的时效性。…

【js面试题】说说new操作符具体干了什么?

JavaScript中的new操作符&#xff1a;深入解析与自定义实现 在JavaScript中&#xff0c;new操作符是一个核心概念&#xff0c;用于创建一个实例对象。理解new的工作原理不仅有助于我们更好地掌握JavaScript的面向对象编程&#xff0c;还能让我们在需要时自定义构造函数的行为。…

Unexpected token d in JSON at position 5, check bodyParser config错误解决

错误原因&#xff1a;json格式不对 { desc"设备1", iotProjectId11 } 解决&#xff1a;通过json在线校验格式校验json格式&#xff0c;找出错误原因&#xff0c;修改 在线JSON校验格式化工具&#xff08;Be JSON&#xff09; 修改&#xff1a; {"desc": &…

一个webpack的plugin 的简单例子

下面是一个简单的 Webpack 插件示例&#xff0c;该插件会在输出目录中创建一个文本文件&#xff0c;并向其中写入当前的时间戳。这个插件演示了如何注册一个监听器&#xff0c;在编译完成之后执行自定义的操作。 首先&#xff0c;你需要创建一个 JavaScript 文件来定义你的插件…

2024年高教杯国赛(E题)数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

Java设计模式【备忘录模式】-行为型

1. 介绍 备忘录模式&#xff08;Memento Pattern&#xff09; 是一种行为型设计模式&#xff0c;允许在不破坏封装的前提下&#xff0c;捕获并保存一个对象的内部状态&#xff0c;然后可以在以后将其恢复到原先保存的状态。备忘录模式的核心思想是记录和恢复对象的状态&#x…

2024年高教社杯全国大学生数学建模竞赛A题思路(2024数学建模国赛A题思路)

A题 “板凳龙” 闹元宵 “板凳龙”,又称“盘龙”,是浙闽地区的传统地方民俗文化活动。人们将少则几十条,多则上百条的板凳首尾相连,形成蜿蜒曲折的板凳龙。盘龙时,龙头在前领头,龙身和龙尾相随盘旋,整体呈圆盘状。一般来说,在舞龙队能够自如地盘入和盘出的前提下,盘龙…

【openwrt-21.02】T750 openwrt MT7916 WPS PBC功能实现

Openwrt版本 NAME="OpenWrt" VERSION="21.02-SNAPSHOT" ID="openwrt" ID_LIKE="lede openwrt" PRETTY_NAME="OpenWrt 21.02-SNAPSHOT" VERSION_ID="21.02-snapshot" HOME_URL="https://openwrt.org/" …

【学习笔记】卫星通信NTN 3GPP标准化进展分析(三)- 3GPP Release17 内容

一、引言&#xff1a; 本文来自3GPP Joern Krause, 3GPP MCC (May 14,2024) Non-Terrestrial Networks (NTN) (3gpp.org) 本文总结了NTN标准化进程以及后续的研究计划&#xff0c;是学习NTN协议的入门。 【学习笔记】卫星通信NTN 3GPP标准化进展分析&#xff08;一&#xff…

MySQL 使用C语言链接

mysql的基础&#xff0c;我们之前已经学过&#xff0c;后面我们只关心使用 要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去官网下载 我们使用C接口库来进行连接 要正确使用&#xff0c;我们需要做一些准备工作&#xff1a; 保证mysql服务有…

MySQL灾难恢复策略:构建稳健的备份与恢复机制

在现代企业环境中&#xff0c;数据的安全性和可靠性至关重要。灾难恢复计划&#xff08;Disaster Recovery Plan, DRP&#xff09;是确保在发生灾难性事件后&#xff0c;能够迅速恢复业务的关键策略。对于依赖MySQL数据库的系统&#xff0c;实现有效的灾难恢复计划尤为重要。本…

信也科技基于 Apache SeaTunnel金融场景的应用实践探索

前言 作者&#xff1a;朱俊&#xff0c;信也科技&#xff0c;数据开发专家 离线开发一直是数据仓库建设中重要的一个环节。信也科技之前基于Azkaban构建了离线任务调度与开发平台&#xff0c;承载了公司90%以上的离线任务调度需求&#xff0c;以及玄策变量平台的每日变量跑批产…