Linux网络编程 linux网络编程书
liebian365 2024-10-14 22:22 42 浏览 0 评论
Socket
一个文件描述符指向一个套接字(套接字内部由内核借助两个缓冲区实现)
网络字节序:
小端法(PC):高位存高地址,地位存地址
大端法(网络):高位存低地址,地位存高地址
TCP/IP协议规定,网络数据流采用大端字节序;而主机当中使用的是小端法,需要做网络字节序和主机字节序的转换。
4字节整数a的存储示意如图所示:
写个小程序,把a的最低位输出来,看看是多少。
#include<stdio.h>
int main(int argc, char const *argv[])
{
printf("%d\n",sizeof(int) );
unsigned int a=0x12345678;
printf("%c\n", a);
printf("%c\n", *((char*)&a+1));
printf("%c\n",*((char*)&a+2));
printf("%c\n", *((char*)&a+3));
return 0;
}
上面程序输出为x,小写x的ASCII值为120,而0x78转换为10进制就是120。
大写V,ASCII值为86,对应16进制为56。可以看出电脑上是小端法存储。
有4个函数专门用于转换:
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
h表示host,n表示network,l表示32位,s表示16位。
htonl:本地->网络(IP)
htons:本地->网络(port)
ntohl:网络->本地(IP)
ntohs:网络->本地(port)
IP地址转换函数
inet_pton:点分十进制字符串转换为网络字节序
inet_ntop:网络字节序转换为点分十进制字符串
这两个函数都支持IPv4和IPv6.
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
af:表示地址类型,只有两个选择,AF_INET表示IPv4,AF_INET6表示IPv6
src:要转换的IP(点分十进制字符串)
det:转换后的网络字节序的IP地址
返回值:
成功:1
异常:0,表示scr指向的不是一个有效的IP地址
失败:-1
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src,char *dst, socklen_t size)
af:AF_INET、AF_INET6
scr:网络字节序的IP地址
dst:本地字节序(string IP)
size:dst的大小
返回值:
成功:dst
失败:NULL;
https://blog.csdn.net/bian_qing_quan11/article/details/71699371
inet_ntoa:网络字节序转换为点分十进制IP
char *inet_ntoa(struct in_addr in);
inet_aton:点分十进制IP转换为网络字节序存放在addr中,成功返回1,失败返回0。
inet_aton() returns 1 if the supplied string was successfully interpreted, or 0 if the string is invalid (errno is not set on
error).
int inet_aton(const char *cp, struct in_addr *inp);
inet_network:将点分十进制IP转化为主机字节序(二进制位小端存储)
in_addr_t inet_network(const char *cp);
inet_addr:将点分十进制IP转化为网络字节序(二进制位的大端存储)。
in_addr_t inet_addr(const char *cp);
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc, char const *argv[])
{
struct in_addr in;
printf("点分十进制ip地址:192.168.1.1\n");
printf("主机字节序:%u\n",inet_network("192.168.1.1"));
inet_aton("192.168.1.1",&in);
printf("网络字节序:%u\n",in.s_addr);
in.s_addr = htonl(inet_network("192.168.1.1"));
printf("点分十进制ip地址:%s\n",inet_ntoa(in));
return 0;
}
192.168.1.1转换成二进制为11000000 10101000 00000001 00000001,转换为十进制为3,232,235,777?,大端存储为00000001 00000001 10101000 11000000,即16,885,952?。
sockaddr数据结构
早期的socket数据结构,sockaddr数据结构其实已经不用了,但因为Linux当中很多函数以前用的这个数据结构,不好对这些函数进行更改,就保留了sockaddr数据结构,它就扮演着void *差不多的角色,用作地址转换中介。例如bind的函数当中参数类型还是sockaddr*类型,使用时需要进行地址类型转换。
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sturct sockaddr_in addr; man 7 ip查看sockaddr_in结构体信息。
addr.sin_family=AF_INT; (sin,socket internet??)
addr.sin_port=htons(9527);
//int dst;
//inet_pton(AR_INET,"11.11.11.11",(void*)&dst);
//add.sin_addr.s_addr=dst;
addr.sin_addr.s_addr=htonl(INADDR_ANY);取出系统中有效的任意IP地址,二进制类型。INADDR_ANY是一个宏。
bind(fd,(struct sockaddr*)&addr,size);
struct sockaddr_in:这个in表示internet,不是进入哈哈(我前两天一直以为是输入,很懵逼)
man 7 ip查看sockaddr_in数据结构
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
sockaddr_un是本地进程通信的数据结构。
socket模型创建流程
socket():创建一个套接字,返回一个文件描述符fd,也叫句柄。
bind():绑定IP+端口
listen():设置监听上线,表示同时能连接的客户端数量
accept():阻塞监听客户端连接
connet(),绑定IP和端口
socket函数
socket()
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain:通信协议,AF_INET、AF_INET6、AF_UNIX、AF_NETLINK等
type:数据传输方式,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等
protocol:对应协议,当protocol为0时,会自动选择type类型对应的默认协议
正如大家所想,一般情况下有了 af 和 type 两个参数就可以创建套接字了,操作系统会自动推演出协议类型,除非遇到这样的情况:有两种不同的协议支持同一种地址类型和数据传输类型。如果我们不指明使用哪种协议,操作系统是没办法自动推演的。
使用 IPv4 地址,参数 af 的值为 PF_INET。如果使用 SOCK_STREAM 传输数据,那么满足这两个条件的协议只有 TCP,因此可以这样来调用 socket() 函数:
int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //IPPROTO_TCP表示TCP协议
返回值:成功返回文件描述符,错误返回-1。
/usr/include/x86_64-linux-gnu/bits/socket.h
/* Protocol families. */
#define PF_UNSPEC 0 /* Unspecified. */
#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */
#define PF_UNIX PF_LOCAL /* POSIX name for PF_LOCAL. */
#define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */
#define PF_INET 2 /* IP protocol family. */
#define PF_AX25 3 /* Amateur Radio AX.25. */
#define PF_IPX 4 /* Novell Internet Protocol. */
#define PF_APPLETALK 5 /* Appletalk DDP. */
#define PF_NETROM 6 /* Amateur radio NetROM. */
#define PF_BRIDGE 7 /* Multiprotocol bridge. */
#define PF_ATMPVC 8 /* ATM PVCs. */
#define PF_X25 9 /* Reserved for X.25 project. */
#define PF_INET6 10 /* IP version 6. */
#define PF_ROSE 11 /* Amateur Radio X.25 PLP. */
#define PF_DECnet 12 /* Reserved for DECnet project. */
#define PF_NETBEUI 13 /* Reserved for 802.2LLC project. */
#define PF_SECURITY 14 /* Security callback pseudo AF. */
#define PF_KEY 15 /* PF_KEY key management API. */
#define PF_NETLINK 16
#define PF_ROUTE PF_NETLINK /* Alias to emulate 4.4BSD. */
#define PF_PACKET 17 /* Packet family. */
#define PF_ASH 18 /* Ash. */
#define PF_ECONET 19 /* Acorn Econet. */
#define PF_ATMSVC 20 /* ATM SVCs. */
#define PF_RDS 21 /* RDS sockets. */
#define PF_SNA 22 /* Linux SNA Project */
#define PF_IRDA 23 /* IRDA sockets. */
#define PF_PPPOX 24 /* PPPoX sockets. */
#define PF_WANPIPE 25 /* Wanpipe API sockets. */
#define PF_LLC 26 /* Linux LLC. */
#define PF_IB 27 /* Native InfiniBand address. */
#define PF_MPLS 28 /* MPLS. */
#define PF_CAN 29 /* Controller Area Network. */
#define PF_TIPC 30 /* TIPC sockets. */
#define PF_BLUETOOTH 31 /* Bluetooth sockets. */
#define PF_IUCV 32 /* IUCV sockets. */
#define PF_RXRPC 33 /* RxRPC sockets. */
#define PF_ISDN 34 /* mISDN sockets. */
#define PF_PHONET 35 /* Phonet sockets. */
#define PF_IEEE802154 36 /* IEEE 802.15.4 sockets. */
#define PF_CAIF 37 /* CAIF sockets. */
#define PF_ALG 38 /* Algorithm sockets. */
#define PF_NFC 39 /* NFC sockets. */
#define PF_VSOCK 40 /* vSockets. */
#define PF_KCM 41 /* Kernel Connection Multiplexor. */
#define PF_QIPCRTR 42 /* Qualcomm IPC Router. */
#define PF_SMC 43 /* SMC sockets. */
#define PF_MAX 44 /* For now.. */
/* Address families. */
#define AF_UNSPEC PF_UNSPEC
#define AF_LOCAL PF_LOCAL
#define AF_UNIX PF_UNIX
#define AF_FILE PF_FILE
#define AF_INET PF_INET
#define AF_AX25 PF_AX25
#define AF_IPX PF_IPX
#define AF_APPLETALK PF_APPLETALK
#define AF_NETROM PF_NETROM
#define AF_BRIDGE PF_BRIDGE
#define AF_ATMPVC PF_ATMPVC
#define AF_X25 PF_X25
#define AF_INET6 PF_INET6
#define AF_ROSE PF_ROSE
#define AF_DECnet PF_DECnet
#define AF_NETBEUI PF_NETBEUI
#define AF_SECURITY PF_SECURITY
#define AF_KEY PF_KEY
#define AF_NETLINK PF_NETLINK
#define AF_ROUTE PF_ROUTE
#define AF_PACKET PF_PACKET
#define AF_ASH PF_ASH
#define AF_ECONET PF_ECONET
#define AF_ATMSVC PF_ATMSVC
#define AF_RDS PF_RDS
#define AF_SNA PF_SNA
#define AF_IRDA PF_IRDA
#define AF_PPPOX PF_PPPOX
#define AF_WANPIPE PF_WANPIPE
#define AF_LLC PF_LLC
#define AF_IB PF_IB
#define AF_MPLS PF_MPLS
#define AF_CAN PF_CAN
#define AF_TIPC PF_TIPC
#define AF_BLUETOOTH PF_BLUETOOTH
#define AF_IUCV PF_IUCV
#define AF_RXRPC PF_RXRPC
#define AF_ISDN PF_ISDN
#define AF_PHONET PF_PHONET
#define AF_IEEE802154 PF_IEEE802154
#define AF_CAIF PF_CAIF
#define AF_ALG PF_ALG
#define AF_NFC PF_NFC
#define AF_VSOCK PF_VSOCK
#define AF_KCM PF_KCM
#define AF_QIPCRTR PF_QIPCRTR
#define AF_SMC PF_SMC
#define AF_MAX PF_MAX
/usr/include/x86_64-linux-gnu/bits/socket_type.h
/* Types of sockets. */
enum __socket_type
{
SOCK_STREAM = 1, /* Sequenced, reliable, connection-based
byte streams. */
#define SOCK_STREAM SOCK_STREAM
SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams
of fixed maximum length. */
#define SOCK_DGRAM SOCK_DGRAM
SOCK_RAW = 3, /* Raw protocol interface. */
#define SOCK_RAW SOCK_RAW
SOCK_RDM = 4, /* Reliably-delivered messages. */
#define SOCK_RDM SOCK_RDM
SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based,
datagrams of fixed maximum length. */
#define SOCK_SEQPACKET SOCK_SEQPACKET
SOCK_DCCP = 6, /* Datagram Congestion Control Protocol. */
#define SOCK_DCCP SOCK_DCCP
SOCK_PACKET = 10, /* Linux specific way of getting packets
at the dev level. For writing rarp and
other similar things on the user level. */
#define SOCK_PACKET SOCK_PACKET
/* Flags to be ORed into the type parameter of socket and socketpair and
used for the flags parameter of paccept. */
SOCK_CLOEXEC = 02000000, /* Atomically set close-on-exec flag for the
new descriptor(s). */
#define SOCK_CLOEXEC SOCK_CLOEXEC
SOCK_NONBLOCK = 00004000 /* Atomically mark descriptor(s) as
non-blocking. */
#define SOCK_NONBLOCK SOCK_NONBLOCK
};
/usr/include/linux/in.h
#if __UAPI_DEF_IN_IPPROTO
/* Standard well-defined IP protocols. */
enum {
IPPROTO_IP = 0, /* Dummy protocol for TCP */
#define IPPROTO_IP IPPROTO_IP
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
#define IPPROTO_ICMP IPPROTO_ICMP
IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
#define IPPROTO_IGMP IPPROTO_IGMP
IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
#define IPPROTO_IPIP IPPROTO_IPIP
IPPROTO_TCP = 6, /* Transmission Control Protocol */
#define IPPROTO_TCP IPPROTO_TCP
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
#define IPPROTO_EGP IPPROTO_EGP
IPPROTO_PUP = 12, /* PUP protocol */
#define IPPROTO_PUP IPPROTO_PUP
IPPROTO_UDP = 17, /* User Datagram Protocol */
#define IPPROTO_UDP IPPROTO_UDP
IPPROTO_IDP = 22, /* XNS IDP protocol */
#define IPPROTO_IDP IPPROTO_IDP
IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
#define IPPROTO_TP IPPROTO_TP
IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
#define IPPROTO_DCCP IPPROTO_DCCP
IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
#define IPPROTO_IPV6 IPPROTO_IPV6
IPPROTO_RSVP = 46, /* RSVP Protocol */
#define IPPROTO_RSVP IPPROTO_RSVP
IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
#define IPPROTO_GRE IPPROTO_GRE
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
#define IPPROTO_ESP IPPROTO_ESP
IPPROTO_AH = 51, /* Authentication Header protocol */
#define IPPROTO_AH IPPROTO_AH
IPPROTO_MTP = 92, /* Multicast Transport Protocol */
#define IPPROTO_MTP IPPROTO_MTP
IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
#define IPPROTO_BEETPH IPPROTO_BEETPH
IPPROTO_ENCAP = 98, /* Encapsulation Header */
#define IPPROTO_ENCAP IPPROTO_ENCAP
IPPROTO_PIM = 103, /* Protocol Independent Multicast */
#define IPPROTO_PIM IPPROTO_PIM
IPPROTO_COMP = 108, /* Compression Header Protocol */
#define IPPROTO_COMP IPPROTO_COMP
IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
#define IPPROTO_SCTP IPPROTO_SCTP
IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
#define IPPROTO_UDPLITE IPPROTO_UDPLITE
IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */
#define IPPROTO_MPLS IPPROTO_MPLS
IPPROTO_RAW = 255, /* Raw IP packets */
#define IPPROTO_RAW IPPROTO_RAW
IPPROTO_MAX
};
#endif
bind()
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
给socket绑定一个地址结构(IP+端口号),socket和sockaddr_in中的地址结构AF_INT等得一样。
sockfd:socket函数返回值,文件描述符
sturct sockaddr_in addr;
addr.sin_family=AF_INT;
addr.sin_port=htons(9527);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr:(struct sockaddr&)&addr,是传入参数
addlen:sizeof(addr),地址结构的大小
返回值:
成功:0;失败:-1
listen()
int listen(int sockfd, int backlog);
设置能够同时与服务器建立连接的客户端上线(同时进行3次握手的客户端数量)
sockfd:socket函数返回值,文件描述符
backlog:上限数值,最大为128。
返回值:
成功:0;失败:-1
accept()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
阻塞等待客户端建立连接,成功时返回一个与客户端成功连接的socket文件描述符
sockfd:最开始建立的socket文件描述符
addr:传出参数,成功与服务器建立连接的那个客户端的地址结构(IP+port)
addrlen:传入传出参数。入:addr的大小,出:客户端addr的实际大小。
socklen_t clit_addr_len = sizeof(struct sockaddr),传入参数&clit_addr_len。
返回值:
成功,返回新建立的socket的文件描述符,非负整数
失败:-1
connect()
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
与服务器建立连接
sockfd:socket函数返回值
addr:传入参数,服务器地址结构
addrlen:服务器地址结构长度
返回值:成功0,失败-1。
如果不使用bind绑定客户端地址结构,系统会“隐式绑定”。
一个简单的例子,
客户端给服务器发一串字符串,服务器将接受到字符串转换为大写,再发功给客户端。
这里用的read、write函数,和recv、send区别后面再研究。
//server.c
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 12345
void sys_error(const char *str)
{
perror(str);
exit(-1);
}
int main(int argc, char const *argv[])
{
int sfd,cfd,ret=0;
socklen_t client_addr_len;
char buf[1024];
char client_IP[16];
struct sockaddr_in server_addr,client_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
sys_error("socket error");
}
ret = bind(sfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
if(ret==-1)
{
sys_error("bind error");
}
ret = listen(sfd,128);
if(ret==-1)
{
sys_error("listen error");
}
client_addr_len = sizeof(client_addr);
cfd = accept(sfd,(struct sockaddr*)&client_addr,&client_addr_len);
if(cfd==-1)
{
sys_error("accept error");
}
//打印连接上的客户端IP和端口号
printf("client_ip:%s port:%d\n",inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_IP,sizeof(client_IP)),ntohs(client_addr.sin_port) );
while(1)
{
ret = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,ret);
for(int i=0;i<ret;i++)
{
buf[i] = toupper(buf[i]);
}
write(cfd,buf,ret);
}
close(sfd);
close(cfd);
return 0;
}
还没有写客户端,可以nc命令模拟客户端
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 12347
void sys_error(const char *str)
{
perror(str);
exit(-1);
}
int main(int argc, char const *argv[])
{
int cfd,ret=0;
char buf[1024];
struct sockaddr_in client_addr,server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
//server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr);
cfd = socket(AF_INET,SOCK_STREAM,0);
if(cfd==-1)
{
sys_error("socket error");
}
ret = connect(cfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
if(ret==-1)
{
sys_error("connect error");
}
while(1)
{
//scanf("%s",buf);
gets(buf);//最好使用fgets。
write(cfd,buf,strlen(buf));
ret = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,ret);
printf("\n");
}
close(cfd);
return 0;
}
TCP三次握手,对应的函数就是accept,connect。
相关推荐
- Linux-常用操作命令介绍(linux常用的命令大全)
-
1.帮助命令帮助命令1.1help命令语法格式:命令--help作用:查看某个命令的帮助信息示例#ls--help#netstat--help1.2man命令语法格式:man命令...
- 推荐:一个小而美的Java工具类库(java工具软件)
-
前言是的,你没看错,没看错,它就是hutool!相信很多做java开发的朋友应该都已经认识并使用过它了,今天带大家再重温一下它都有哪些功能,并以示例来看看hutool是如何简便实现JWT认...
- 【SpringBoot后端开发】第三部分 Linux操作系统常用命令(3)
-
创作不易,请帮忙转发、点赞和评论!四、Linux常用命令对于Linux系统来说,中央处理器、内存、磁盘驱动器、键盘、鼠标、用户等都是文件,而Linux系统管理的命令是它正常运行的核心,与之DOS命令类...
- linux常用命令在线查询工具(linux常用命令在线查询工具有哪些)
-
linuxvi编辑器常用命令linux查看iplinuxfind-name查找文件名linuxshelllinux查看端口占用linux删除文件命令linuxcp命令复制文件到另一个...
- 使用免费绿色工具chfs,将文件夹共享成网盘
-
需求:业务需求方有个需要将apk包上传到服务器中,通过chfs可以将服务器目录共享出来,可以可以登录后台自行上传apk文件包。本文就教大家三个知识点1.centos7下使用chfs,共享目录。2.使用...
- Mysql和Hive之间通过Sqoop进行数据同步
-
文章回顾理论大数据框架原理简介大数据发展历程及技术选型实践搭建大数据运行环境之一搭建大数据运行环境之二本地MAC环境配置CPU数和内存大小查看CPU数sysctlmachdep.cpu#核数为...
- 真实案例记录Linux被植入rootkit导致服务器带宽跑满的解决过程
-
一、关于linux下的rootkitrootkit是Linux平台下最常见的一种木马后门工具,它主要通过替换系统文件来达到攻击和和隐蔽的目的,这种木马比普通木马后门更加危险和隐蔽,普通的检测工...
- python周期任务调度工具Schedule使用详解
-
如果你想周期性地执行某个Python脚本,最出名的选择应该是Crontab脚本,但是Crontab具有以下缺点:不方便执行秒级任务。当需要执行的定时任务有上百个的时候,Crontab的管...
- Linux 系统日常巡检脚本(shell巡检脚本)
-
Linux系统日常巡检脚本,巡检内容包含了,磁盘,内存cpu进程文件更改用户登录等一系列的操作直接用就行了。报告以邮件发送到邮箱在log下生成巡检报告。#!/bin/bash#@Au...
- Schedule—简单实用的 Python 周期任务调度工具
-
如果你想周期性地执行某个Python脚本,最出名的选择应该是Crontab脚本,但是Crontab具有以下缺点:1.不方便执行秒级任务。2.当需要执行的定时任务有上百个的时候,Cronta...
- celery定时与异步任务详解(定时任务异步执行)
-
celery简介Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。Celery的架构由三部分组成,消息中间件(messagebroke...
- 开源免费的定时任务管理系统:Gocron
-
Gocron:精准调度未来,你的全能定时任务管理工具!-精选真开源,释放新价值。概览Gocron是github上一个开源免费的定时任务管理系统。它使用Go语言开发,是一个轻量级定时任务集中调度和管理...
- PHP Laravel定时任务Schedule(laravel定时任务原理)
-
前提:本文方法是利用Linux的crontab定时任务来协助实现Laravel调度(Mac也一样)。一、首先添加Crontab定时任务,这里只做简单介绍:用命令crontab-e添加如下内容**...
- Linux的常用命令就是记不住,怎么办?于是推出了这套教程
-
1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...
- 如何定期执行 Python 脚本:5 种常见方法
-
定期执行任务是自动化工作流程中的重要环节,无论是数据抓取、文件备份,还是定期报告生成,定时运行脚本都可以极大提高效率。本文将介绍五种方法,通过这些方法,你可以轻松设置定期执行Python脚本的任务...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)