一,定义:

1,单播用于两个主机之间的端对端通信,广播用于一个主机对整个局域网上所有主机上的数据通信。单播和广播是两个极端,单播对一个主机进行通信,广播对整个局域网上的主机进行通信。

多播,也称为“组播”,将局域网中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。

2,IP地址 和 子网掩码的概念
(1)IP地址的概念和分类
 IP地址本质就是在互联网中的唯一地址标识,其数据类型为32位二进制组成的整数(ipv4),当然也有128位二进制组成的整数(ipv6)。日常生活中描述IP地址的主要形式为: 点分十进制表示法,也就是将每8位二进制转换为一个十进制整数,不同的十进制整数之间通过小数点分隔;
如:0x01020304  =>  1.2.3.4

查看IP地址的方式:
     windows系统中: ipconfig    ipconfig/all
     linux系统中: ifconfig    /sbin/ifconfig

IP地址主要分为两部分:  网络地址  +  主机地址,根据网络地址和主机地址的划分,将IP地址分为以下4类:
     A类:0 + 7位网络地址 +  24位主机/本地地址
     B类:10 + 14位网络地址 + 16位主机/本地地址
     C类:110 + 21位网络地址 + 8位主机/本地地址
     D类:1110 + 28位多播地址

(2)子网掩码的概念
     子网掩码本质就是用于帮助IP划分具体的网络地址和主机地址,也可以用于判断两个IP地址是否在同一个局域网中,具体的划分方法为:按位&运算进行
如:
    IP地址:172.30.100.41
    子网掩码:255.255.255.0

3,端口号和字节序的概念
(1)端口号
     IP地址 - 互联网中的地址标识,通过该地址可以定位主机
     端口号 - 主要用于定位某一台主机上的具体进程
     端口号的数据类型是:unsigned short类型,范围是:0 ~ 65535,其中0 ~ 1024之间的端口由系统占用,因此编程指定端口号时,建议从1025开始使用
     网络编程中需要提供:IP地址  +  端口号

(2)字节序的概念
小端系统:低位内存地址存放低位数据的系统
大端系统:低位内存地址存放高位数据的系统
如:对于十六进制的数据 0x12345678来说
小端系统中按照地址从小到大依次:0x78 0x56 0x34 0x12
大端系统中按照地址从小到大依次:0x12 0x34 0x56 0x78

二,单播(分为tcp和udp一对一)

1,基于Socket的一对一通信模型
基本概念: Socket  -  本意为插座的意思,表示逻辑上的通信载体

基本模型:
服务器:
    (1)创建socket,使用socket函数
    (2)准备通信地址,使用结构体变量
    (3)绑定socket和    通信地址,使用bind函数
    (4)进行通信,使用read/write函数
    (5)关闭socket,使用close函数
客户端:
    (1)创建socket,使用socket函数
    (2)准备通信地址,是服务器的地址
    (3)连接socket和通信地址,使用connect函数
    (4)进行通信,使用read/write函数
    (5)关闭socket,使用close函数

2,.基于tcp协议的网络通信模型
服务器:
     (1)创建socket,使用socket函数
     (2)准备通信地址,使用结构体类型
     (3)绑定socket和通信地址,使用bind函数
     (4)监听,使用listen函数
     (5)响应客户端的连接请求,使用accept函数
     (6)进行通信,使用read/write函数
     (7)关闭socket,使用close函数
客户端:
     (1)创建socket,使用socket函数
     (2)准备通信地址,使用服务器的地址
     (3)连接socket和通信地址,使用connect函数
     (4)进行通信,使用read/write函数
     (5)关闭socket,使用close函数

3,基于udp协议的通信模型

服务器:
     (1)创建socket,使用socket函数
     (2)准备通信地址,使用结构体类型
     (3)绑定socket和通信地址,使用bind函数
     (4)进行通信,使用sendto/recvfrom函数
     (5)关闭socket,使用close函数
客户端:
     (1)创建socket,使用socket函数
     (2)准备通信地址,使用服务器的地址
     (3)进行通信,使用sendto/recvfrom函数
     (4)关闭socket,使用close函数

三,组播

1,实际情况下经常需要对一组特定的主机进行通信,而不是整个局域网上的所有主机,这就是组播的用途。组播的地址是特定的,D类IP地址用于组播地址,即224.0.0.0至239.255.255.255之间的IP地址,并被划分为局部连接组播地址、预留组播地址和管理权限组播地址3类:

局部组播地址:在224.0.0.0~224.0.0.255之间,这是为路由协议和其他用途保留的地址,路由器并不转发属于此范围的IP包。
预留组播地址:在224.0.1.0~238.255.255.255之间,可用于全球范围(如Internet)或网络协议。
管理权限组播地址:在239.0.0.0~239.255.255.255之间,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制组播范围。

属于永久组的地址:224.0.0.1   所有组播主机224.0.0.2   所有组播路由器224.0.0.4   DRMRP路由器224.0.0.5   所有OSPF的路由器224.0.0.6   OSPF指派路由器224.0.0.9   RPIv2路由器224.0.0.10  EIGRP路由器224.0.0.13  PIM路由器224.0.0.22  IGMPv3224.0.0.25  RGMP224.0.1.1   NTP网络时间协议

2,组播编程流程

(1)建立一个socket;
(2)设置组播的参数,例如超时时间TTL,本地回环许可LOOP等
(3)加入组播组
(4)发送和接收数据
(5)从组播组离开

3,组播主机的三个级别:

0级:主机不能发送或接收I P组播。

这种主机应该自动丢弃它收到的具有D类目的地址的分组。

1级:主机能发送但不能接收I P组播。

在向某个I P组播组发送数据报之前,并不要求主机加入该组。组播数据报的发送方式与单播一样,除了组播数据报的目的地址是 I P组播组之外。网络驱动器必须能 够识别出这个地址,把在本地网络上组播数据报。

2级:主机能发送和接收I P组播。

为了接收I P组播,主机必须能够加入或离开组播组,而且必须支持IGMP,能够在至少一个接口上交换组成员信息。多接口主机必须支持在它的接口的一个子网上的组播Net/3符合2级主机要求,可以完成组播路由器的工作。与单播IP选路一样,我们假定所描述的系统是一个组播路由器,并加上了Net/3组播选路的程序。

4,组播程序设计

使用setsockopt()函数和getsockopt()函数来实现,组播的选项是IP层的。

**getsockopt()/setsockopt()**的选项含义

IP_MULTICAST_TTL设置组播组数据的TTL值IP_ADD_MEMBERSHIP在指定接口上加入组播组IP_DROP_MEMBERSHIP退出组播组IP_MULTICAST_IF获取默认接口或设置接口IP_MULTICAST_LOOP禁止组播数据回送

(1)选项IP_MULTICASE_TTL

选项IP_MULTICAST_TTL允许设置超时TTL,范围为0~255之间的任何值,

例如:unsigned char ttl=255;   setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));
(2)选项IP_MULTICAST_IF

选项IP_MULTICAST_IF用于设置组播的默认默认网络接口,会从给定的网络接口发送,另一个网络接口会忽略此数据。例如:

struct in_addr addr;

setsockopt(s,IPPROTO_IP,IP_MULTICAST_IF,&addr,sizeof(addr));

参数addr是希望多播输出接口的IP地址,使用INADDR_ANY地址回送到默认接口。

默认情况下,当本机发送组播数据到某个网络接口时,在IP层,数据会回送到本地的回环接口,选项IP_MULTICAST_LOOP用于控制数据是否回送到本地的回环接口。例如:

unsigned char loop;

setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop));参数loop设置为0禁止回送,设置为1允许回送。
(3)选项IP_ADD_MEMBERSHIP和IP_DROP_MEMBERSHIP

加入或者退出一个多播组,通过选项IP_ADD_MEMBERSHIP和IP_DROP_MEMBER- SHIP,对一个结构struct ip_mreq类型的变量进行控制,struct ip_mreq原型如下:

struct ip_mreq
{struct in_addr imn_multiaddr;/*加入或者退出的广播组IP地址*/struct in_addr imr_interface;/*加入或者退出的网络接口IP地址*/
};

选项IP_ADD_MEMBERSHIP用于加入某个多播组,之后就可以向这个多播组发送数据或者从多播组接收数据。此选项的值为mreq结构,成员imn_multiaddr是需要加入的多播组IP地址,成员imr_interface是本机需要加入广播组的网络接口IP地址。例如:

struct ip_mreq mreq;

setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));

5,linux下组播服务器和客户端编程一:

(1)服务器

持续向多播IP地址"224.0.0.22"的0x8006端口发送数据"BROADCAST TEST DATA",发送间隔5s。

/*
*broadcast_server.c -组播服务程序
*/#define MCAST_PORT 0x8006;
#define MCAST_ADDR “224.0.0.22”//*一个局部连接多播地址,路由器不进行转发*/
#define MCAST_DATA “BROADCAST TEST DATA”/*组播发送的数据*
#define MCAST_INTERVAL 5/*发送间隔时间*/
int main(int argc, char*argv)
{int s;struct sockaddr_in mcast_addr;s = socket(AF_INET, SOCK_DGRAM, 0);/*建立套接字*/if (s == -1){perror(“socket()”);return -1;}memset(&mcast_addr, 0, sizeof(mcast_addr));/*初始化IP组播地址为0*/mcast_addr.sin_family = AF_INET;/*设置协议族类行为AF*/mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*设置组播IP地址*/mcast_addr.sin_port = htons(MCAST_PORT);/*设置组播端口*//*向组播地址发送数据*/while(1) {int n = sendto(s,/*套接字描述符*/MCAST_DATA,/*数据*/sizeof(MCAST_DATA),/*长度*/0,(struct sockaddr*)&mcast_addr,sizeof(mcast_addr)) ;if( n < 0){perror(“sendto()”);return -2;}sleep(MCAST_INTERVAL);/*等待一段时间*/}return 0;
}

(2)客户端

组播组的IP地址为224.0.0.22,端口为0x8006,当客户端接收到组播的数据后将打印出来。

客户端只有在加入组播组后才能接受组播组的数据,因此组播客户端在接收组播组的数据之前需要先加入组播组,当接收完毕后要退出组播组。

/**broadcast_client.c -组播的客户端*/
#define MCAST_PORT 0x8006;
#define MCAST_ADDR “224.0.0.22”/*一个局部连接多播地址,路由器不进行转发*/
#define MCAST_INTERVAL 5/*发送间隔时间*/
#define BUFF_SIZE 256/*接收缓冲区大小*/
int main(int argc, char*argv[])
{int s;/*套接字文件描述符*/struct sockaddr_in local_addr;/*本地地址*/int err = -1;s = socket(AF_INET, SOCK_DGRAM, 0);/*建立套接字*/if (s == -1){perror(“socket()”);return -1;}/*初始化地址*/memset(&local_addr, 0, sizeof(local_addr));local_addr.sin_family = AF_INET;local_addr.sin_addr.s_addr = htonl(INADDR_ANY);local_addr.sin_port = htons(MCAST_PORT);/*绑定socket*/   err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;if(err < 0){perror(“bind()”);return -2;}/*设置回环许可*/int loop = 1;err = setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));if(err < 0){perror(“setsockopt():IP_MULTICAST_LOOP”);return -3;}struct ip_mreq mreq;/*加入多播组*/mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*网络接口为默认*//*将本机加入多播组*/err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));if (err < 0){perror(“setsockopt():IP_ADD_MEMBERSHIP”);return -4;}int times = 0;int addr_len = 0;char buff[BUFF_SIZE];int n = 0;/*循环接收多播组的消息,5次后退出*/for(times = 0;times<5;times++){addr_len = sizeof(local_addr);memset(buff, 0, BUFF_SIZE);/*清空接收缓冲区*//*接收数据*/n=recvfrom(s,buff,BUFF_SIZE,0,(struct sockaddr*)&local_addr,&addr_len);if( n== -1){perror(“recvfrom()”);}printf("Recv %dst message from server:%s ", times, buff);//打印信息sleep(MCAST_INTERVAL);}/*退出多播组*/err=setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq));close(s);return 0;}
}

6,linux下组播编程二:

(1)服务器代码

#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#define BUFLEN 255
int main(int argc, char **argv)
{struct sockaddr_in peeraddr;struct in_addr ia;int sockfd;char recmsg[BUFLEN + 1];unsigned int socklen, n;struct hostent *group;struct ip_mreq mreq;/* 创建 socket 用于UDP通讯 */sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket\n");exit(errno);}printf("socket created success!!!\n");/* 设置要加入组播的地址 */bzero(&mreq, sizeof(struct ip_mreq));if (argv[1]){if ((group = gethostbyname(argv[1])) == (struct hostent *)0) {perror("gethostbyname");exit(errno);}} else {printf("you should give me a group address, 224.0.0.0-239.255.255.255\n");exit(errno);}bcopy((void *)group->h_addr, (void *)&ia, group->h_length);printf("组播地址:%s\n", inet_ntoa(ia));/* 设置组地址 */bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr));/* 设置发送组播消息的源主机的地址信息 */mreq.imr_interface.s_addr = htonl(INADDR_ANY);/* 把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息 */if(setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(struct ip_mreq))==-1) {perror("setsockopt");exit(errno);}socklen = sizeof(struct sockaddr_in);memset(&peeraddr, 0, socklen);peeraddr.sin_family = AF_INET;if (argv[2]){peeraddr.sin_port = htons(atoi(argv[2]));}else{peeraddr.sin_port = htons(4567);}if (argv[1]) {if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {printf("Wrong dest IP address!\n");exit(0);}} else {printf("no group address given, 224.0.0.0-239.255.255.255\n");exit(errno);}/* 绑定组播地址的端口和IP信息到socket上 */if(bind(sockfd,(struct sockaddr*)&peeraddr,sizeof(struct sockaddr_in))==-1) {printf("Binded failure\n");exit(0);} else{printf("binded success!!!\n");}/* 循环接收网络上来的组播消息 */for (;;) {bzero(recmsg, BUFLEN + 1);n=recvfrom(sockfd,recmsg,BUFLEN, 0,(struct sockaddr *)&peeraddr,&socklen);if (n < 0) {printf("recvfrom error in udptalk!\n");exit(errno);} else {/* 成功接收到数据报 */recmsg[n] = 0;printf("peer info:%s", recmsg);}}return 0;
}

(2)客户端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define BUFLEN 255
int main(int argc, char **argv)
{struct sockaddr_in peeraddr;int sockfd;char recmsg[BUFLEN + 1];unsigned int socklen;/* 创建 socket 用于UDP通讯 */sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket\n");exit(errno);}printf("socket created success!!!\n");socklen = sizeof(struct sockaddr_in);/* 设置对方的端口和IP信息 */memset(&peeraddr, 0, socklen);peeraddr.sin_family = AF_INET;if (argv[2])peeraddr.sin_port = htons(atoi(argv[2]));elsepeeraddr.sin_port = htons(4567);if (argv[1]) {/* 注意这里设置的对方地址是指组播地址,而不是对方的实际IP地址 */if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0){printf("wrong group address!\n");exit(0);}} else {printf("no group address!\n");exit(0);}/* 循环接受用户输入的消息发送组播消息 */for (;;){/* 接受用户输入 */bzero(recmsg, BUFLEN + 1);if (fgets(recmsg, BUFLEN, stdin) == (char *)EOF)exit(0);/* 发送消息 */if(sendto(sockfd, recmsg, strlen(recmsg), 0,(struct sockaddr *)&peeraddr,         sizeof(struct sockaddr_in)) < 0) {printf("sendto error!\n");exit(errno);}printf("client sendto success!\n");}return 0;
}

(3)运行

$ gcc -o client client.c
$ gcc -o server server.c$ ./client 234.1.2.3 4567
socket created success!!!
just to test!
client sendto success!$ ./server 234.1.2.3 4567
socket created success!!!
组播地址:234.1.2.3
binded success!!!
peer info:just to test!

四,广播

1,在windows上接收广播使用setsockopt结合SO_BROADAST。同样的代码不能在linux上获得同样的效果。使用tcpdump监听,可以收到了广播包:

2,服务器端广播循环发送一个文件,客户端持续接收文件。

​ <服务器端或客户端谁先运行均可,文件名由命令行指定>

服务端运行:./server wj.txt       客户端运行:./client

(1)服务器代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#define LEN  256
int main(int argc, char **argv)
{struct sockaddr_in server_socket;int sockfd = 0;int on = 1;int num = 0;char msg[LEN] = {0};if (argc < 2){perror("Usage error: need a filename\n");exit(1);}sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket():Create socket fails!\n");exit(1);}//设置套接字为广播模式  SO_BROADCASTsetsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));memset(&server_socket,0,sizeof(server_socket)); server_socket.sin_family = AF_INET;//inet_pton是一个IP地址转换函数,可以在将点分文本的IP地址转换为二进制网络字节序”的IP地址if (inet_pton(AF_INET, "255.255.255.255", &server_socket.sin_addr) <= 0) {perror("inet_pton():IP address is error!\n");exit(1);}server_socket.sin_port = htons(1234);int fd;int len;fd = open(argv[1],O_RDONLY);if(fd == -1){perror("open failed\n");exit(1);}char begin_signal[LEN]="new transmission begin!\n\n";while(1){sendto(sockfd, begin_signal, strlen(begin_signal), 0, (struct sockaddr *)&server_socket, sizeof(struct sockaddr_in));        while((len = read(fd,msg,10)) > 0){sendto(sockfd, msg, len, 0, (struct sockaddr *)&server_socket, sizeof(struct sockaddr_in));}lseek(fd,0,SEEK_SET); //移动读指针至文件起始位置sleep(3);}close(fd);close(sockfd);exit(0);
}

(2)客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define LEN  256
int main(int argc, char **argv)
{struct sockaddr_in client_socket;int sockfd = 0;int num = 0;char msg[LEN] = {0};sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket():Create socket fails!\n");exit(1);}memset(&client_socket, 0, sizeof(client_socket));client_socket.sin_family = AF_INET;client_socket.sin_port = htons(1234);client_socket.sin_addr.s_addr = htonl(INADDR_ANY); int opt = SO_REUSEADDR;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));if(bind(sockfd,(struct sockaddr *)&client_socket,sizeof(struct sockaddr_in))<0){perror("bind():bind fails!\n");exit(1);}while(1)  //这里不使用while(1)依然可以持续接收{while((num = read(sockfd, msg, LEN)) > 0){write(1,msg,num);}}close(sockfd);exit(0);
}

组播,单播和广播相关相关推荐

  1. 动态路由协议的分类、动静态路由优缺点、RIP简介、组播单播广播详解(附图)

    目录 一.动态路由协议的分类 (1)按照工作区域范围: (2)按照路由算法: RIP相关知识简介: 二.静态路由优缺点: 三. 动态路由优缺点: 四.单播.组播.广播详解: 一.动态路由协议的分类 ( ...

  2. 组播,单播,广播,多播,泛洪的概念

    一.什么是组播: 1.组播的特点 1)什么是组播?       组播是一种数据包传输方式,当有多台主机同时成为一个数据包的接受者时,出于对带宽和CPU负担的考虑,组播成为了一种最佳选择. 2)组播如何 ...

  3. 单播、多播(组播)和广播的差别

    单播.多播和广播单播"(Unicast)."多播"(Multicast)和"广播"(Broadcast)这三个术语都是用来描写叙述网络节点之间通讯方式 ...

  4. 计算机网络——单播、多播(组播)、广播

    一.单播(一对一通信) 主机之间一对一的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制.如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作.但由于其能够针对每个客户 ...

  5. 单播 、多播(组播)、广播

    作者:yhthu 链接:https://www.jianshu.com/p/cc62e070a6d2#comments 来源:简书 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. ...

  6. 关于socket组播和ssdp(一)[修改1.2]

    有关于ssdp安全的文章 ssdp攻击和防御 组播 单播和广播 组播方式解决了单播情况下数据的重复拷贝及带宽的重复占用,也解决了广播方式下带宽资源的浪费,我们知道单播在发送者和每一接收者之间实现点对点 ...

  7. 单播、广播、多播(组播)的概念和区别

    单播.广播.多播(组播)的概念和区别 简单理解如下: 1.一台机器和一台机器通信这是单播. 2.一台机器发出的数据包能被多台机器收到这就叫组播. 一个机器发送,多台机器接收,但是又不同于广播, 发送端 ...

  8. IP网络通信的单播、组播和广播

    一.判断两台设备是否在同一局域网内 查看两台设备的ip4地址和子网掩码MASK. 若MASK不一样,则不在同一局域网内. 若MASK一样,分别计算IP&MASK.若二者相同,则在同一局域网,否 ...

  9. 单播 广播 组播区别

    一:通信方式分类 在IPv4网络中,主机可采用的通信方式有如下三种: 1.单播:单台主机与单台主机之间的数据通信 带宽端口有多少台就发多少个数据 2.广播:单台主机向网络中所有主机发送数据包的过程 发 ...

最新文章

  1. GitHub率先消灭了cookies:与烦人的用户条款说再见
  2. GPU上的相似性检查(PNSR和SSIM)
  3. angular-cli更新(link方式安装)
  4. IT从业的迷思与破解之道(更新)
  5. PHP在不同页面间传递Json数据示例代码
  6. 跨系统服务器data,跨服务器的数据整合方法及系统 Cross-server data integration method and system...
  7. python判断一个数是否是质数
  8. css hack 记录
  9. Open XML之我见
  10. 在Linux中smbfs文件系统的挂载
  11. 苹果录屏没声音_通过AppleALC,轻松解决黑苹果没声音问题
  12. rssi室内定位算法原理_基于RSSI的室内定位算法
  13. windows系统更新失败无法启动的解决方法
  14. Django支付宝在线支付
  15. Android应用市场转移【2021-03-22】
  16. linux 删除文件的最后一行
  17. 闪付卡(QuickPass)隐私泄露原理(重要文章)
  18. 站内信功能 java_站内信功能
  19. No.118 Pascal's Triangle ||
  20. 【Python】Pandas读取tsv文件

热门文章

  1. 简单python脚本 爬取杭州链家二手房 房价信息
  2. Java中表头的边框置为实线,div的边框线为实线怎么样设置
  3. IDL 一维数组的Sen斜率实现
  4. 集装箱交接清单(CTNJJD)
  5. 定位教程7---旋转中心标定之方法二
  6. 诺奖得主罗杰错了?“宇宙在大爆炸之前就存在”毫无根据可言!
  7. 单一功能学习——百度AI之身份证识别
  8. 2020全球顶尖计算机科学家排名发布:两位华人学者入全球前10,Top 1000华人学者过百...
  9. 移动硬盘中毒后文件丢失但所占空间还在的解决办法
  10. intellij idea下使用复制粘贴键没法用了,失效