[1] 历史
    1. 网络的产生
       1957                     Sputnik
       1958                     国防高级项目研究局(Defense Advanced Research Projects Agency 简称: DARPA)
       1968                     ARPAnet(NCP, 不支持不同OS、不同类型的计算机之间的通信, 不支持纠错)
       
    2. TCP协议产生
       1972                     Robert Kahn被DARPA雇佣研究卫星和地面通信
       1973                     NCP协议的制定者Vinton Cerf也加入DARPA,研究封包交换网络
                                (ARPAnet  封包无线网   封包卫星网)
       1973                     Robert Kahn 和Vinton Cerf一起制定TCP(Transmission Control Protocol)
                                (支持不同OS 不同类型的计算机之间的通信 纠错)
       
    3. TCP/IP协议产生
       1974                     实时性数据传输要求TCP(纠错 跨网络传输) = TCP(纠错) + IP(跨网络传输)
                                同时加入UDP(User Datagram Protocol)协议, 不支持纠错
                                
       什么实时性数据?
       优酷看电影
       
       为什么实时性数据传输要求TCP协议分解?
       (1) 错误产生原因
           TCP协议纠错(检测错误, 错误的包采取重传)---网络条件不好(重传数据包)--->数据传输延迟
       
       (2) 解决办法
           1. 可靠性要求比较高的数据(QQ文字)
              TCP + IP
              
           2. 实时性要求比较高的数据,可靠性要求向对不高(QQ视频)
              UDP + IP
       
    4. TCP/IP协议大规模使用
       1983                      BSD(unix)实现TCP/IP协议,随着BSD系统大规模使用,TCP/IP协议也得到了大规模使用
       
[2] 基本概念
    1. 封包
       对数据的一种封装,类似于"包裹"
       
    2. 协议
       通信双方预定好的数据包(封包)格式,类似于快递公司让我们在约定的地方填写“收货人电话和地址”
       
    3. Internet(互联网)
       连接网络的网络
       (1) 早期
    
          
                                     用户数据
                                      (货物)
           ----------------------------------------------------------------
           TCP(Transmission Control Protocol)  UDP(User Datagram Protocol)
                                      (包裹)
           ----------------------------------------------------------------
                                IP(Internet Protocol)
                                      (集装箱)
           ----------------------------------------------------------------
           ARPA网                    封包无线网                  封包卫星网 
           (公路网)                   (水路网)                    (航空网)
           
           1. TCP(可靠)
              面向连接(类似于电话,先拨通,才能说话)
              纠错(保证数据不丢失、无错误、无失序、无重复到达)
              
           2. UDP(不可靠)
              不面向连接
              不纠错
              
       (2) 现在
           主要框架和早期网络完全相同,主要的协议仍然采用TCP/IP协议,
           但是向里面加入了很多其他协议,以适应新的应用需求。
           具体协议见PPT
           telnet               远程登录协议
           FTP                  File Transfer Protocol
           HTTP                 HyperText Transfer Protocol
           DNS                  Domain Name System
           SMTP                 Simple Mail Transfer Protocol
           ICMP                 Internet Control Message Protocol
           IGMP                 Internet Group Management Protocol
           FDDI                 Fiber Distributor Data Interface
           TFTP                 简化版的FTP
           PPP                  Point to Point Protocol
           ARP                  Address Resolution Protocol
           RARP                 Reverse Address Resolution Protocol
           MTU                  Maximum Transmission Unit
           
       (3) 理想(OSI)
       
           应用数据                     应用层
           -------------------------------------
           安全加密和应用协议           表示层     应用层
           -------------------------------------   
           建立连接(电话)               会话层
           ----------------------------------------------------
           TCP或UDP协议                            传输层
           -----------------------------------------------------
           IP协议                                  网络层
           -----------------------------------------------------
           硬件相适应的协议                        数据链路层
           -----------------------------------------------------
           硬件连接                                物理层
           
   4. RFC(Request For Comments)征求意见书(搜索)
      官网网站: http://www.ietf.org/
      
[3] 家庭网络如何工作?
    1. A电脑和B电脑(虚拟机)如何通信?
       A电脑(telnet)-->B电脑(telnetd)
       
    2. A电脑如何和baidu通信?
       百度
        
[4] 资料&工具
    1. 资料
       《TCP/IP协议详解卷一》
       
    2. 工具
       WireShark           局域网内的抓包工具
       
[5] 网络参数设置
    1. ip地址
       (1) 作用
           网络中唯一标示一台主机
           
       (2) 组成
           网络地址 + 主机号
           网络地址: 用于区分两台主机是否在同一个网络之内,类似于电话区号
           主机号:   用于区分同一个网络内的两台主机
           
       (3) 长度
           IPv4        32bit
           IPv6        128bit
           
       (4) 字节序(2.字节序目录下)
           网络字节序--大端
           
       (5) 表示方法(点分十进制)
           将IP地址中的4个字节,分别用10进制表示出来,然后用"."分隔开来的写法
           例: 192     .168     .1       .1
               11000000 10101000 00000001 00000001
               
       (6) 分类
               网络地址长度   主机号长度    高位规定   地址范围            私网(局域网)地址        保留地址
           A        1             3         0          0.x.x.x-127.x.x.x   10.x.x.x                127.x.x.x(环回地址)
           B        2             2         10         128.x.x.x-191.x.x.x 172.16.x.x-172.32.x.x   169.254.x.x(表示网络中没有DHCP服务器)
           C        3             1         110        192.x.x.x-223.x.x.x 192.168.x.x
           D            组播                1110
           E            保留
           注意:网络地址      主机号为0的地址
                 广播地址      主机号为全1的地址, 例: 192.168.0.255
                 
    2. 子网掩码(mask)
       IP & mask = 网络地址
       IP & ~mask = 主机号
       
       例: 
       十进制                      二进制
       IP地址   192.168.0.88       11000000 10101000 00000000 01011000
      &子网掩码 255.255.255.0      11111111 11111111 11111111 00000000
      ----------------------------------------------------------------
                192.168.0.0        11000000 10101000 00000000 00000000
                
       思考: IP地址根据范围可以获取地址类型,根据地址类型,可以知道网络地址位数
             为什么还需要子网掩码?
             有时候需要将C类地址的局域网分成更小的相互独立的局域网,可以将主机地址拿
             一部分出来做,网络地址,这时就可以达到,将C类地址组成的局域网分成更小的
             局域网的目的,比如:
                    十进制                      二进制
       IP地址   192.168.0.88       11000000 10101000 00000000 01011000
      &子网掩码 255.255.255.0      11111111 11111111 11111111 11100000
      ----------------------------------------------------------------
                192.168.0.0        11000000 10101000 00000000 01011111
        
    3. 网关
       一个网络通向另一个网络的关口
       (A电脑<----网关---->baidu)
       
    4. DNS服务器
       将域名(计算机名)---->IP地址
       www.baidu.com        服务器IP地址
       
[6] A电脑(telnet)-->B电脑(telnetd)
    A电脑网络参数:
    网卡地址     00-0C-29-D5-D3-EE
    IP地址       192.168.0.159
    网关         192.168.0.1
    DNS服务器    192.168.0.1
    
    B电脑(虚拟机)网络参数:
    网卡地址     00:0c:29:9e:bc:b8
    IP地址       192.168.0.249
    网关         192.168.0.1
    DNS服务器    192.168.0.1
    
    (1) 计算机A: IP(计算机B)---ARP(地址解析协议)--->网卡地址(计算机B的)(MAC地址)
    (2) 计算机A: TCP协议包----B电脑的网卡地址--->计算机B
    (3) 计算机B: TCP协议包----A电脑的网卡地址--->计算机A
    (4) 计算机A: TCP协议包----B电脑的网卡地址--->计算机B
    (5) 计算机B: telnet协议包---B电脑的网卡地址--->计算机B
    
    A电脑--->baidu
    (1) 计算机A: www.baidu.com---DNS协议包--->IP地址(baidu)         网关是DNS服务器
    (2) 计算机A: TCP协议包---网关的网卡地址--->网关---baidu的IP地址--->baidu
    (3) baidu:   TCP协议包---网关的IP地址--->网关---A电脑的网卡地址--->A电脑
    (4) 计算机A: TCP协议包---网关的网卡地址--->网关---baidu的IP地址--->baidu
    (5) 计算机A: HTTP协议包---网关的网卡地址--->网关---baidu的IP地址--->baidu
    
    计算机<----网关---->baidu
    
    端口号:
    1. 作用
       在同一台机器中,唯一标识一个进程,用于接收到数据包时,知道是发给哪个进程的
       
    2. 长度
       16bit
       
    3. 分类
       1-1023           知名端口号(已经分配给有名的服务程序, telnet(23), ...)
       1024-49151       注册端口号(非知名的服务程序,注册的端口号)
       49152-65535      动态分配端口号(系统自动分配给应用程序)
       
    
       
[7] 数据包格式
    ARP
    ---------------------------------------
    dest mac | src mac | ARP协议数据
    ---------------------------------------
    
    TCP
    ---------------------------------------------------
    dest mac | src mac | src ip | dest ip | TCP协议数据
    ---------------------------------------------------
    
    telnet
    ------------------------------------------------------------------------------
    dest mac | src mac | src ip | dest ip | src port | dest port | telnet 协议数据
    ------------------------------------------------------------------------------
    
    思考: 发送数据给目标机器上的目标程序,至少告诉发送程序,目标程序的哪些信息?
          目标机器的IP地址
          目标程序的端口号
          
[8] linux系统网络实现
    应用层                                    data    应用程序
    ----------------------------------------------------------
    socket编程接口(所有操作系统接口完全相同)
    -------------------------------------------------
    传输层                         TCP(UDP) + data    
    -------------------------------------------------  内核
    网络层                    IP + TCP(UDP) + data
    -------------------------------------------------
    数据链路层          ETH + IP + TCP(UDP) + data
    ----------------------------------------------------------
    物理层                                             硬件
    
[9] socket
    1. 历史
       1982                 本地通信
       1986                 网络编程
       
    2. 原理
       一种特殊的文件
       
    3. 目的
       将通信操作模拟成文件操作
        
    4. 类型及用途
       SOCK_STREAM(流式套接字)          TCP
       SOCK_DGRAM(报文套接字)           UDP
       SOCK_RAW(原始套接字)             IP协议、ICMP协议

[10] ip地址转换

    // 1. 头文件#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>// 2. 数据结构typedef unsigned int in_addr_t;struct in_addr {unsigned int s_addr;}; //定义成结构体的好处://可扩展性强//类型检查更严格struct in_addr addr;struct in_addr1 {unsigned int s_addr;}; (in_addr1)addr;                //语法上是错误的//  3. 函数//ip字符串--->32bit整数(网络字节序--大端)/** @param[in]      cp                                          ip字符串* @param[out] inp                                         整数形式的IP地址* @return             @li !0                         cp中的IP地址有效*             @li 0                                      cp中的IP地址无效*/int inet_aton(const char *cp, struct in_addr *inp);/** @param[in]      cp                                          ip字符串* @return             整数形式的IP地址*              @li INADDR_NONE(-1)            cp中的IP地址无效* @notes             bug                                         -1(255.255.255.255是有效的IP地址,不过目前没有用到)*/in_addr_t inet_addr(const char *cp);//32bit整数(网络字节序--大端)--->ip字符串/** @param[in]        in                                          整数形式的IP地址* @return             ip字符串*/char *inet_ntoa(struct in_addr in);

[12] 整数的字节序转换

   //  1. 头文件#include <arpa/inet.h>//  2. 函数//主机字节序--->网络字节序/** @param[in]     hostlong(hostshort)       主机字节序的整数* @return            网络字节序的整数*/uint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t hostshort);//网络字节序--->主机字节序/** @param[in]       hostlong(hostshort)       网络字节序的整数* @return            主机字节序的整数*/uint32_t ntohl(uint32_t hostlong);uint16_t ntohs(uint16_t hostshort);

[13] 练习
     编写一个order程序,完成如下操作:
     ./order 192.168.0.88 8888
     (1) 将IP地址和端口转换成网络字节序打印
     (2) 将网络字节序的IP地址和端口转换回IP字符串和主机字节序的端口,打印

#include <stdio.h>
#include <stdlib.h>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>// ./order 192.168.0.88 8888
int main(int argc, const char *argv[])
{in_addr_t net_ip;unsigned short net_port;struct in_addr addr;if (argc < 3){fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);exit(EXIT_FAILURE);}// 转成网络字节序,打印net_ip = inet_addr(argv[1]);net_port = htons(atoi(argv[2]));printf("net_ip = %08x, net_port = %04x\n", net_ip, net_port);// 转换回主机字节序, 打印// addr.s_addr = net_ip;printf("ip = %s, port = %d\n", inet_ntoa(*((struct in_addr *)(&net_ip))), ntohs(net_port));return 0;
}

[14] UDP数据通讯原理
     UDP数据通讯分服务端(软件)和客户端端:
     服务端(软件)(服务器)先运行,服务端,不需要事先知道客户端IP和port
     客户端(软件)(客户端机器)后运行,一定是客户端先给服务端发包,客户端一定先知道服务端的IP和port
     
[15] UDP通信实现

   // 1. 头文件#include <sys/types.h>     #include <sys/socket.h>//  2. 数据结构// Internet协议地址结构struct sockaddr{// 地址的通信领域unsigned short int sa_family;  // ip(4B) 和 port(2B) char sa_data[14];};// 通用数据结构struct sockaddr_in {unsigned short int sin_family;unsigned short int sin_port;     // portstruct in_addr sin_addr;         // ip地址// 填充0 (8B)unsigned char sin_zero[sizeof (struct sockaddr) -(sizeof (unsigned short int)) -sizeof (unsigned short int) -sizeof (struct in_addr)];};      

3. 函数
        服务端流程
        (1) 创建套接字(创建并且打开套接字)

            /** @param[in]                      domain                          通信领域*                                           @li AF_UNIX, AF_LOCAL       unix域套接字通信(本机进程间)*                                         @li AF_INET                 IPv4协议通信*                                          @li AF_INET6                IPv6协议通信* @param[in]                      type                            套接字类型*                                          @li SOCK_STREAM            流式套接字*                                          @li SOCK_DGRAM         报文套接字*                                          @li SOCK_RAW           网络层的协议访问* @param[in]                       protocol                        协议标识*                                           @li 0              使用默认协议*                      * @return                                                                             文件描述符*                                          @li -1             创建失败(错误码见errno)*/int socket(int domain, int type, int protocol);

(2) 绑定ip地址和port(到socket(一定一个进程创建))

            /** @param[in]                      sockfd                          socket* @param[in]                     addr                            绑定地址(ip地址和port)* @param[in]                        addrlen                         addr的字节数                               * @return                           @li 0                          绑定成功*                               @li -1                                     创建失败(错误码见errno)*/int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

(3) 接收数据包

            /** @param[in]                      sockfd                          socket* @param[out]                            buf                         接收数据包的buf* @param[in]                      len                         buf的字节数 * @param[in]                       flags                           0* @param[out]                         src_addr                            源地址(IP和Port)*                               @NULL                        不接收源地址,此时addrlen也必须为NULL   * @param[in | out]                                 addrlen(输入)                     src_addr缓冲区字节数*                                                          addrlen(输出)                        实际地址大小             * @return                           @li >= 0                       实际接收的字节数*                               @li -1                         创建失败(错误码见errno)*/ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

(4) 发送数据包

            /** @param[in]                      sockfd                          socket* @param[out]                            buf                             发送数据包的buf* @param[in]                      len                         发送数据的字节数 * @param[in]                      flags                                   0* @param[out]                         dest_addr                       目标地址(IP和Port)* @param[in]                      addrlen                         dest_addr字节数            * @return                          @li >= 0                       实际发送的字节数*                               @li -1                         发送失败(错误码见errno)*/ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

(5) 关闭socket

int close(int sockfd);
        
        客户端流程
        (1) 创建套接字(创建并且打开套接字)
        (2) 发送数据包
        (3) 接收数据包
        (4) 关闭socket

客户端:

/** 实现目标:* udp客户端* * 实现步骤:* 1. 创建socket(创建并打开套接字文件)* 2. 接收用户输入* 3. 发送用户输入到服务端* 4. 接收并显示服务端返回* 5. 关闭socket**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <strings.h>// net
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>// ./client <server ip> <server port>
int main(int argc, const char *argv[])
{int sockfd;int len;char packet[1024] = {'\0'};struct sockaddr_in server_addr;struct sockaddr_in client_addr;socklen_t addrlen = sizeof(struct sockaddr_in);if (argc < 3) {fprintf(stderr, "Usage: %s <server ip> <server port>\n", argv[0]);exit(EXIT_FAILURE);}// 1. 创建socket(创建并打开套接字文件)sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd) {perror("Fail to socket.");exit(EXIT_FAILURE);}bzero(&server_addr, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(atoi(argv[2]));server_addr.sin_addr.s_addr = inet_addr(argv[1]);while (strcmp(packet, "bye") != 0) {// 2. 接收用户输入putchar('\r');putchar('>');fgets(packet, sizeof(packet), stdin);packet[strlen(packet) - 1] = '\0';// 3. 发送用户输入到服务端len = sendto(sockfd, packet, strlen(packet), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));if (len == -1) {perror("Fail to sendto");exit(EXIT_FAILURE);}// 4. 接收并显示服务端返回len = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&server_addr, &addrlen);if (-1 == len) {perror("Fail to recvfrom.");exit(EXIT_FAILURE);}packet[len] = '\0';printf("------------------------------\n");printf("%s\n", packet);printf("------------------------------\n");}// 5. 关闭socketclose(sockfd);return 0;
}

服务端:

/** 实现目标:* UDP服务端* * 实现步骤:* 1. 创建socket(创建并打开套接字文件)* 2. 绑定ip和端口到socket* 3. 接收数据* 4. 发送相同数据回客户端* 5. 关闭socket**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <strings.h>// net
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>// server <ip> <port>
int main(int argc, const char *argv[])
{int len;int sockfd;char packet[1024] = {'\0'};struct sockaddr_in server_addr;struct sockaddr_in peer_addr;socklen_t addrlen = sizeof(struct sockaddr_in);if (argc < 3) {fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);exit(EXIT_FAILURE);}// 1. 创建socket(创建并打开套接字文件)sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd) {perror("Fail to socket.");exit(EXIT_FAILURE);}// 2. 绑定ip和端口到socketbzero(&server_addr, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(atoi(argv[2]));server_addr.sin_addr.s_addr = inet_addr(argv[1]);if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Fail to bind.");exit(EXIT_FAILURE);}while (1) {// 3. 接收数据len = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&peer_addr, &addrlen);if (-1 == len) {perror("Fail to recvfrom.");exit(EXIT_FAILURE);}packet[len] = '\0';printf("------------------------------\n");printf("ip   : %s\n", inet_ntoa(peer_addr.sin_addr));printf("port : %d\n", ntohs(peer_addr.sin_port));printf("recv : %s\n", packet);printf("------------------------------\n");// 4. 发送相同数据回客户端len = sendto(sockfd, packet, strlen(packet), 0, (struct sockaddr *)&peer_addr, sizeof(peer_addr));if (len == -1) {perror("Fail to sendto");exit(EXIT_FAILURE);}}// 5. 关闭socketclose(sockfd);return 0;
}

Linux Tcp/ip UDP基本概念(6.8)相关推荐

  1. Linux TCP/IP协议栈之Socket的实现分析

    数据包的接收 作者:kendo http://www.skynet.org.cn/viewthread.php?tid=14&extra=page%3D1 Kernel:2.6.12 一.从网 ...

  2. linux 协议栈之socket,Linux TCP/IP 协议栈之 Socket 的实现分析(一)

    内核版本:2.6.37 参考[作者:kendo的文章(基于内涵版本2.6.12)] 第一部份 Socket套接字的创建 socket 并不是 TCP/IP协议的一部份. 从广义上来讲,socket 是 ...

  3. linux TCP/IP L2层数据包接收流程,eth_rxnetif_receive_skb处理流程

    linux TCP/IP L2 handle 流程, 基于Linux kernel3.14.

  4. 追踪Linux TCP/IP代码运行--基于2.6内核(……

    查看书籍详细信息: 追踪Linux TCP/IP代码运行--基于2.6内核(-- 内容简介 本书以应用程序为线索,详细描述了数据包在协议栈的分段.重组.发送.接收过程,同时分析了路由的初始化和设置过程 ...

  5. QT入门第七天 网络编程TCP/IP/UDP+Http和JSON解析+qt事件软键盘【CSDN最详细】

    网络编程+Http和JSON解析+qt事件软键盘 第一章 QT中的网络编程 [1]涉及到的类 [2]tcp协议的流程 [2.1]服务器的流程 socket-->bind-->listen- ...

  6. Linux TCP/IP大合集

    简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp. 文件描述符的操作(如: open)返回的是一个文件描述符,内核会在 ...

  7. Linux TCP/IP网络协议栈:IP协议源码分析

    目录 IP协议简介 IP头部 IP数据包的发送 IP数据包的接收 https://mp.weixin.qq.com/s/8WNcTxtD4DBcNtcrR8nz4Q IP协议 是网络的最重要部分,毫不 ...

  8. [转]Linux TCP/IP 协议栈的关键数据结构Socket Buffer(sk_buff )

    因为太喜欢这篇文章,所以有保存在自己blog里的冲动,同时也对文章代码的相关部分加上了颜色,给阅读时黑压压的一片带来一些亮色,也减少了阅读时的单调情愫. sk_buff结构可能是linux网络代码中最 ...

  9. 基础(网络知识 三)——网络系统各层协议分析总结(TCP/IP/UDP/HTTP.....)

    网络系统按照分层的思想设计了当下的网络系统结构,主要是TCP/IP四层网络结构,各层是如何工作的呢?每一层都有相关的协议,各协议具体是什么?原理与作用是什么?本节主要总结介绍网络层的相关协议规则,从而 ...

最新文章

  1. JAVA面向对象的特征
  2. linux gitlab 9 邮件不发送,gitlab无法发送邮件
  3. PCM音频基础知识及采样数据处理
  4. IPM: Six right dimensions limitation
  5. vb趣味编程弹球小游戏_最好玩的微信小游戏集合,总有一款是你没玩过的
  6. 工作113:声明问题 的定义变量
  7. 【转载】理解矩阵(一)
  8. MapReduce三种join实例分析
  9. spider和python的关系_Scrapy框架-Spider和CrawlSpider的区别
  10. python 面试相关
  11. 浅析局域网聊天软件的能力
  12. 13个适合上班时做的保健小动作
  13. Vue.js删除子组件数据显示异常,重新销毁创建子组件
  14. SpringCloud熔断机制大概什么意思
  15. 【天光学术】新闻学论文:校园网络流行语传播社会热点问题的途径(节选)
  16. win10配置docker环境
  17. 为什么总是黑php,怎么都在黑PHP?
  18. 达人评测锐龙r7 5800h和酷睿i7 12650h选哪个好
  19. python语言表白超炫图形_经验分享 篇二:三分钟教你用Excel制作各种尺寸、底色的证件照...
  20. java基础知识之加强

热门文章

  1. 新一轮商业革命将至,张勇用“敏捷组织”率先交出答卷
  2. HPU数学基础训练level1
  3. 【JoJo的摄影笔记】相机配件之奥义——风林火山
  4. java http头_JAVA如何获取HTTP请求头
  5. Elasticsearch搜素引擎入门
  6. 光电技术与光纤基础期末复习笔记
  7. python-图片批量处理大小并删除原图片
  8. 进销存管理(FIFO,LIFO)
  9. starring V6平台开发接出点流程
  10. 【第175期】游戏策划的跳槽:做决定前,建议你要知道的两个事