嵌入式学习——网络编程(UDP)——day30

2024-06-03 10:36

本文主要是介绍嵌入式学习——网络编程(UDP)——day30,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 协议

        通信双方约定的一套标准成为协议

2. 国际网络协议标准

2.1 OSI七层模型(理论模型)

            应用层:传输的数据(a.out)
            表示层:数据是否加密
            会话层:是否需要建立会话链接(网络断开连接状态)
            传输层:传输数据的方式(TCP、UDP)
            网络层:数据路由(IP地址)
            数据链路层:局域网内的数据传输(交换机局域网内多设备的链接)
            物理层:物理介质链接(网线、电缆  硬件高低电平)

2.2 TCP/IP网络协议模型(实际开发)

            应用层
            传输层
            网络层
            网络接口层(链路+物理)

        1. 应用层协议

                FTP  TFTP  HTTP  SMTP  TELNET 

        2. 传输层协议——UDP、TCP

              UDP:用户数据报协议(无连接)
                    特点:
                    1.不安全、不可靠
                    2.数据量小
                    3.占用资源开销小
              TCP:传输控制协议(有链接)
                    特点:
                    1.安全、可靠
                    2.数据量大
                    3.占用资源开销大

                三次握手建立链接
                数据传输过程中双方通过序列号和确认号保障数据传输完整性
                四次挥手结束链接

        3. 网络层协议——局域网

        3.1 IPv4

        (1)IP:192.168.0.189    ——   网络位(192.198.0)    主机位(189)

                IP地址 = 网络位 + 主机位

                    网络位:IP地址所在的网段    

                    主机位:在局域网内的主机编号

        (2)子网掩码:搭配IP地址使用,区分IP地址中的网络位和主机位

                                   子网掩码是1的部分对应IP地址网络位

                                   子网掩码是0的部分对应IP地址主机位

        (3)网段号:网络位不变,主机位全为0的IP地址——192.168.0.0

                 广播号:网络位不变,主机位全为1的IP地址——192.168.0.255

                        (给广播号发送一个信息,所有的IP地址都能搜到)

        (4)IP地址的分类

                A类:1.0.0.0 - 126.255.255.255
                    子网掩码:255.0.0.0
                    管理大规模网络
                    私有IP:10.0.0.0 - 10.255.255.255
        
                B类:128.0.0.0 - 191.255.255.255
                    子网掩码:255.255.0.0 
                    管理大中规模网络
                    私有IP:172.16.0.0 - 172.31.255.255 
        
                C类:192.0.0.0 - 223.255.255.255
                    子网掩码:255.255.255.0 
                    管理中小规模网络
                    私有IP:192.168.0.0 - 192.168.255.255 
        
                D类:224.0.0.0 - 239.255.255.255
                    用于组播传输(给一组人传输数据)
        
                E类:240.0.0.0 - 255.255.255.254 
                    用于科研实验

                公有IP地址:能够直接上网的IP地址(路由器)
                私有IP地址:不能直接上网的IP地址(个人主机)

        (5)MAC地址:网卡地址  物理地址(此地址不会重复,是唯一的)

        (6)端口号:唯一识别同一主机不同进程的号码

                (0 - 65535)(不要使用10000以内的,10000以内的是系统的)

        (7)注意

                  IP地址是为了找某一个网段、MAC地址是为了找在局域网中找到某一个主机

4. UDP编程——不论对方是否收到都能完成发送

4.1 socket

      int socket(int domain, int type, int protocol);
      功能:
        创建一个用来进程通信的套接字,返回文件描述符
      参数:
        domain:AF_INET           IPv4协议族
        type:SOCK_STREAM    流式套接字            tcp传输协议
             SOCK_DGRAM    数据报套接字            udp传输协议
             SOCK_RAW        原始套接字            
        protocol:
            默认为0 
      返回值:
        成功返回套接字新文件描述符
        失败返回-1 

4.2 sendto

      ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);
      功能:
        给另一个套接字发送消息
      参数:
        sockfd:套接字文件描述符
        buf:要发送数据存放空间的首地址
        len:要发送数据的长度
        flags:发送属性  默认为0 
        dest_addr:目的地址
        addrlen:目的地址信息长度
      返回值:
        成功返回发送字节个数
        失败返回-1 
    
    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 */(IP地址)
   };

   /* Internet address. */
   struct in_addr {
       uint32_t       s_addr;     /* address in network byte order */
   };

4.3 inet_addr

      in_addr_t inet_addr(const char *cp);
      功能:
        将字符串IP地址转换为二进制IP地址 
      参数:
        cp:字符串IP地址空间首地址
      返回值:
        成功返回二进制IP地址

4.4 htons

      uint16_t htons(uint16_t hostshort);
      功能:
        将本地字节序(小端)转换为网络字节序(大端)
      参数:
        hostshort:本地端口号
      返回值:
        返回网络字节序端口号
        
      uint16_t ntohs(uint16_t netshort);
      功能:
        将网络字节序(大端)转换为本地字节序(小端)

4.5 bind

      int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);
      功能:
        将套接字与IP地址端口绑定在一起
      参数:
        sockfd:文件描述符 
        addr:结构体空间首地址 
        addrlen:信息的长度
      返回值:
        成功返回0 
        失败返回-1 

4.6 recvfrom

      ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
      功能:
        接收数据
      参数:
        sockfd:套接字文件描述符
        buf:存放接收到数据空间的首地址
        len:最多允许接收的字节数
        flags:属性 默认为0 
        src_addr:存放发送端地址信息空间首地址
        addrlen:想要接收发送端地址大小的变量空间首地址
      返回值:
        成功返回实际接收字节数
        失败返回-1 
        
    注意:
        该函数具有阻塞功能

4.7 UDP编程示例代

(1)单方向收发

        1.  头文件

#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>#endif

              2  发送端代码(send.c)

#include "head.h"int main(int argc, char const *argv[])
{int sockfd = 0;char tmpbuff[1024] = {"hello world"};struct sockaddr_in recvaddr;ssize_t nsize = 0;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.155");nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff)+1, 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == nsize){perror("fail to sendto");return -1;}printf("send %ld bytes success\n", nsize);close(sockfd);return 0;
}

                3. 接收端代码(recv.c)

#include "head.h"int main(int argc, char const *argv[])
{int sockfd = 0;int ret = 0;ssize_t nsize = 0;char tmpbuff[4096] = {0};struct sockaddr_in recvaddr;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.155");ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret){perror("fail to bind");return -1;}nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, NULL, NULL);if (-1 == nsize){perror("fail to recvfrom");return -1;}printf("recv %ld bytes success\n", nsize);printf("RECV:%s\n", tmpbuff);close(sockfd);return 0;
}

 (2)双向通信

        1. 头文件

#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>#endif

        2. 发送端

#include "head.h"int main(int argc, char const *argv[])
{int sockfd = 0;char tmpbuff[4096] = {"你在吗?"};struct sockaddr_in recvaddr;ssize_t nsize = 0;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}	recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.155");nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff)+1, 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == nsize){perror("fail to sendto");return -1;}memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, NULL, NULL);if (-1 == nsize){perror("fail to recvfrom");return -1;}printf("RECV:%s\n", tmpbuff);close(sockfd);return 0;
}

        3. 接收端

#include "head.h"int main(int argc, char const *argv[])
{int sockfd = 0;int ret = 0;struct sockaddr_in recvaddr;struct sockaddr_in sendaddr;char tmpbuff[4096] = {0};ssize_t nsize = 0;socklen_t addrlen = sizeof(sendaddr);sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}	recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.155");ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret){perror("fail to bind");return -1;}nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, (struct sockaddr *)&sendaddr, &addrlen);if (-1 == nsize){perror("fail to recvfrom");return -1;}printf("[%s:%d]%s\n", inet_ntoa(sendaddr.sin_addr), ntohs(sendaddr.sin_port), tmpbuff);sprintf(tmpbuff, "%s --------echo", tmpbuff);nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));if (-1 == nsize){perror("fail to sendto");return -1;}close(sockfd);return 0;
}

                

这篇关于嵌入式学习——网络编程(UDP)——day30的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1026747

相关文章

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.