嵌入式开发学习日志(linux系统编程--网络编程)Day33

网络编程

用于不同主机间的通信;

一、OSI模型

(1)应用层:

(2)表示层:加密解密

(3)会话层:网络断开,连接状态

(4)传输层:tcp:传输控制协议可靠通信;udp:用户数据报协议,不可靠通信

(5)网络层:ip地址

(6)链路层:网络设备、交换机

(7)物理层:硬件设备

应用层:为网络用户提供各种服务,例如电子邮件、文件传输等。
表示层:为不同主机间的通信提供统一的数据表示形式。
会话层:负责信息传输的组织和协调,管理进程会话过程。

传输层:管理网络通信两端的数据传输,提供可靠或不可靠的传输服务。

网络层:负责数据传输的路由选择和网际互连。


数据链路层:负责物理相邻(通过网络介质相连)的主机间的数据传输,主要作用包括物理地址寻址、数据帧封装、差错控制等。该层可分为逻辑链路控制子层(LLC)和介质访问控制子层(MAC)。
物理层,负责把主机中的数据转换成电信号,再通过网络介质(双绞线、光纤、无线信道等)来传输。该层描述了通信设备的机械、电气、功能等特性。

二、tcp/ip模型

应用层   ====》应用程序
传输层   ====》端口号tcp udp
网络层   ====》IP 地址
接口层   ====》网卡 驱动  1GB

TCP/IP协议族:
    www.taobao.com(称为域名) ---> 192.168.0.19        
    www.voa.com  
    dns 域名解析
    DHCP(动态主机配置协议)
    应用层: HTTP TFTP(简单文件传输,局域网范围) FTP(互联网文件传输) SNMP DNS ...
    传输层: TCP(传输控制协议)  UDP(用户数据报协议)   56k猫
    网络层: IP(互联网协议)  ICMP(互联网控制管理协议网络检测诊断)(ping) RIPOSPF IGMP ...
    物理层: ARP(地址解析协议)  RARP  ...   ip--->mac
    arp,,,,
 

三、IP地址

1、IP地址的分类

网络基础 ===》A B C D E 类

010 3333344444
IP地址 == 网络位 + 主机位

IP地址的分类: 点分十进制   ipv4  712934


A类: 超大规模性网络


1.0.0.0 - 126.255.255.255  126.1.1.1 
126.1.1.2
255.0.0.0    
私有:
10.0.0.0 - 10.255.255.255
127.0.0.1


B类: 大中规模型网络(前两位为网络号,后面分给主机)


128.0.0.0 - 191.255.255.255
128.2.1.2  128.2.7.2
255.255.0.0
私有:
172.16.0.0 - 172.31.255.255


C类: 中小规模型网络(局域网,前三组代表网络号,后一组分给主机)


192.0.0.0 - 223.255.255.255
255.255.255.0
私有:
192.168.0.0 - 192.168.255.255
静态路由
192.168.0.0
192.168.0.1  网关
192.168.0.255 

 C 类网络:
    ip地址的前三组是网络地址,第四组是主机地址。
二进制的最高位必须是: 110xxxxx开头
十进制表示范围: 192.0.0.0 -223.255.255.255
默认网络掩码:   255.255.255.0
网络个数: 2^24 个 约 209 万个
主机个数: 2^8  个 254 个+2 ===》1 是网关 1是广播
私有地址: 192.168.x.x 局域网地址。


D类: 组播和广播


224.0.0.0 - 239.255.255.255
192.168.0.255 ==  255.255.255.255
235.1.2.3
192.168.1.0 
192.168.0.1   网关
192.168.1.255 广播 


E类: 实验


240.0.0.0 - 255.255.255.255
 

 2、网络配置

sudo vim  /etc/network/interfaces //网络配置

                                        //接口

        auto ens33启动网络设备

        iface ens33 inet dhcp自动获取ip地址


  sudo /etc/init.d/networking restart      //网络重置命令


 sudo reboot        //重启

3、单机上网的配置:


    1、有网络接口并插入网线。
    2、有ip地址
    3、配置网络设置

            ip: ifconfig ethX X.X.X.X/24 up  ifconfig ens33 192.168.0.13/24 up  255.255.255.0

                     查询本机IP                                           //设置IP地址,临时性,重启就没有了


            网关: route add default gw x.x.x.x 
            DNS:  vi /etc/resolv.conf  ==>nameserver 8.8.8.8
            测试:ping www.baidu.com  //检查能否上网

            netstat  -anp        //网络状态/

 4、网络接口

1、socket  套接字(第一种表示:网络设备对应的文件描述符) ==》BSD socket ==》(第二种表示)用于网络通信的一组接口函数。socket api  application interface
2、ip+port 地址+端口===》地址用来识别主机
                             端口用来识别应用程序:用于找进程

          port分为TCP port / UDP port  范围都是: 1-65535
          约定1000 以内的端口为系统使用。
            http 80   www.baidu.com
                3306
                telnet 21 
                ssh 22

 5、网络字节序

网络字节序 ===》大端存储        主机字节序
        12 00   小端   0x12345678
        00 12
        192.168.0.12
        12.0.168.192

 四、网络编程(udp)

udp的特征

嵌入式开发学习日志(linux系统编程--网络编程)Day33_第1张图片

服务端:提供网络服务

客户端:使用网络服务

在网络程序,是客户端找服务器,服务器不能找客户端,故服务端需使用bind来绑定端口号;

 嵌入式开发学习日志(linux系统编程--网络编程)Day33_第2张图片

 1、socket函数

#include          /* See NOTES */
#include

形式:

        int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符

参数:domain  地址族,PF_INET == AF_INET ==>互联网程序
                                       PF_UNIX == AF_UNIX ==>单机程序
           type    套接字类型:
                SOCK_STREAM  流式套接字 ===》TCP   
                SOCK_DGRAM   用户数据报套接字===>UDP
                SOCK_RAW     原始套接字  ===》IP
      protocol 协议 ==》0 表示自动适应应用层协议。(前面已经描述清楚,TCP\UDP都填0)

返回值:成功 返回申请的套接字id,  失败  -1;

/2、bind函数

int bind(int sockfd, struct sockaddr *my_addr, 
             socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关的文件描述符文件与参数2 指定的接口地址关联, 用于从该接口接受数据。

      如果该函数在客户端调用,则表示要将数据从参数1所在的描述符中取出并从参数2所在的接口设备上发送出去。

      注意:如果是客户端,则该函数可以省略,由默认接口发送数据。
参数:sockfd 之前通过socket函数创建的文件描述符,套接字id
      my_addr 是物理接口的结构体指针。表示该接口的信息。

      struct sockaddr      通用地址结构
      {
          u_short sa_family;  地址族
          char sa_data[14];   地址信息
      };

      转换成网络地址结构如下:
      struct _sockaddr_in    ///网络地址结构
      {
          u_short           sin_family; 地址族
          u_short           sin_port;   ///地址端口,一般建议值大于50000,使用htons(host to net short),进行地址转换(将一个无符号短整型数值转换为网络字节序,即大端模式)
          struct in_addr  sin_addr;   ///地址IP,使用函数inet_addr(192.168.116.130);将字符串(小端)转为大端
          char               sin_zero[8]; 占位
      };

      struct in_addr
      {
          in_addr_t s_addr;
      }

      socklen_t addrlen: 参数2 的长度。
返回值:成功 0,失败  -1;

3 recvfrom函数

ssize_t recvfrom(int sockfd, void *buf, size_t len,             int flags,                          
                              收到buf     大小        一般默认为0 ,无人发送时阻塞
struct sockaddr *src_addr, socklen_t *addrlen);
    对方地址                   大小:int len = sizeof(cli);
                                    &len

4 sendto函数

ssize_t sendto(int sockfd, const char *buf, size_t len, int flags, 
                            发生buf内容
const struct sockaddr *dest_addr, socklen_t addrlen);
发给谁
  • 注意:对于客户端,ser内容保留,获取iP地址;
  • 当谁回应是确定的,recvfrom的地址为null,大小也为null;
  • 若完成,关闭套接字,close(); 

5 网络编程之 UDP  用户数据报 

1、特性: 无链接  不可靠  大数据   

2、框架: C/S模式 

   server:socket() ===>bind()===>recvfrom()===>close()
   client:socket() ===>bind()===>sendto() ===>close()


注意:socket()的参数需要调整。

      socket(PF_INET,SOCK_DGRAM,0);

      bind() 客户端是可选的,服务器端是比选的。

发送函数:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
             const struct sockaddr *dest_addr, socklen_t addrlen);


功能:用于UDP协议中向对方发送数据。
参数:sockfd  本地的套接字id
      buff    本地的数据存储,一般是要发送的数据。
      len     要发送的数据长度
      flags   要发送数据方式,0 表示阻塞发送。

      dest_addr: 必选,表示要发送到的目标主机信息结构体。
      addrlen :目标地址长度。

返回值:成功  发送的数据长度, 失败   -1;

接收函数:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                  struct sockaddr *src_addr, socklen_t *addrlen);

功能:用于UDP协议中获取对方发送的数据。
参数:sockfd 本地的套接字id
      buff   要存储数据的内存区,一般是数组或者动态内存。
      len    要获取的数据长度,一般是buff的大小。
      flags  获取方式,0 阻塞

      src_addr 可选,表示对方的地址信息结构体,
                  如果为NULL,表示不关心对方地址。
      addrlen  对方地址信息结构体大小。
                  如果对方地址是NULL,则该值也为NULL。
返回值:成功 接收到的数据长度
        失败  -1;

 服务端: 

#include 
#include 
#include 
#include           /* See NOTES */
#include 
#include 
#include  /* superset of previous */ 
#include 
#include 
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{
    int sockfd  = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        return 1;
    }
    struct sockaddr_in ser,cli;//client  man 7 ip 
    bzero(&ser,sizeof(ser));
    bzero(&cli,sizeof(cli));
    ser.sin_family  = AF_INET;
    ser.sin_port = htons(50000); // host to net short 
    ser.sin_addr.s_addr = inet_addr("192.168.0.199");// 小端转大端
    int ret = bind(sockfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("bind");
        return 1;
    }
    socklen_t len = sizeof(cli);
    while(1)
    {
        char buf[256]={0};
        recvfrom(sockfd,buf,sizeof(buf),0,(SA)&cli,&len);

        time_t tm;
        time(&tm);
        struct tm * tminfo = localtime(&tm);

        sprintf(buf,"%s %d:%d:%d\n",buf,tminfo->tm_hour,tminfo->tm_min
                ,tminfo->tm_sec);
     
        sendto(sockfd,buf,strlen(buf),0,(SA)&cli,sizeof(cli));
    }
    
    return 0;
}

客户端:

#include 
#include 
#include 
#include           /* See NOTES */
#include 
#include 
#include  /* superset of previous */ 
#include 
#include 
#include 
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{
    int sockfd  = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        return 1;
    }
    struct sockaddr_in ser,cli;//client  man 7 ip 
    bzero(&ser,sizeof(ser));
    bzero(&cli,sizeof(cli));
    ser.sin_family  = AF_INET;
    ser.sin_port = htons(50000); // host to net short 
    ser.sin_addr.s_addr = inet_addr("192.168.0.161");// 小端转大端
    socklen_t len = sizeof(cli);
    while(1)
    {
        char buf[256]={0};
        strcpy(buf,"this is udp test");
        sendto(sockfd,buf,strlen(buf),0,(SA)&ser,sizeof(ser));
        bzero(buf,sizeof(buf));
        recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
        printf("server:%s",buf);
        sleep(1);
    }
    close(sockfd);
    return 0;
}

你可能感兴趣的:(嵌入式开发学习,网络,学习,服务器)