C/C++网络编程基础知识超详细讲解第二部分(系统性学习day12)

简介: C/C++网络编程基础知识超详细讲解第二部分(系统性学习day12)

一、UDP编程

UDP特点:

   UDP的特点:不要连接,只管发送,数据因此不稳定,易丢包。      

   UDP与TCP不同之处:

       1>没有服务器跟客户端的观念

       2>没有accept和connect

       3>UDP实际对于网络需求略高一点

UDP框架:

发送端 :                                                  

           1>创建socket套接字                    

           2>绑定自己的IP地址和端口号            

           3>声明别人的IP地址和端口号            

           4>发送数据(函数有变化)                

接收端:

           1>创建socket套接字

           2>绑定自己的IP地址和端口号

           3>声明别人的IP地址和端口号

           4>接收数据(函数有变化)

UDP函数学习

1>sendto

           #include <sys/types.h>

           #include <sys/socket.h>

       int sendto(int sockfd, const void *buf, int len, unsigned int flags,

                   const struct sockaddr *dest_addr, int addrlen);

       功能:

           发送数据(用第五参数定位对方的IP地址和端口号)

       参数:

           sockfd:套接字

           buf:发送缓冲区

           len: 发送缓冲区的长度

           flags:默认为0

           dest_addr:结构体(包含目标的IP和端口号)

           addrlen:结构体的长度

       返回值:

           成功返回发送字节数

           失败,返回-1,并设置错误码

           

       2>recvfrom

           #include <sys/types.h>

           #include <sys/socket.h>

       int recvfrom(int sockfd, const void *buf, int len, unsigned int flags,

               const struct sockaddr *src_addr, socklen_t *addrlen);

       功能:

           接收数据(用第五参数定位对方的IP地址和端口号)

       参数:

           sockfd:套接字

           buf:接收缓冲区

           len: 接收缓冲区的长度

           flags:默认为0

           src_addr:结构体(包含目标的IP和端口号)

           addrlen:结构体的长度的指针

       返回值:

           成功返回接收字节数

           失败,返回-1,并设置错误码

发送端代码案例如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc,char *argv[])
{
  if(argc<5)
  {
    printf("请输入<./可执行> <自己IP> <自己端口号> <目标IP> <目标端口号>\n");
    return -1;
  }
  //1>创建socket套接字
  int sfd;
  sfd = socket(AF_INET,SOCK_DGRAM,0);//注意换UDP类型
  if(sfd<0)
  {
    perror("socket");
    return -1;
  }
  //2>绑定自己的IP和端口号
  struct sockaddr_in myself;
  myself.sin_family = AF_INET;
  myself.sin_port = htons(atoi(argv[2])); //9000
  myself.sin_addr.s_addr = inet_addr(argv[1]);
  if(bind(sfd,(struct sockaddr *)&myself,sizeof(myself))<0)
  {
    perror("bind");
    return -1;
  }
  //3>声明别人的IP和端口号
  struct sockaddr_in other;
  other.sin_family = AF_INET;
  other.sin_port = htons(atoi(argv[4]));  //8888
  other.sin_addr.s_addr = inet_addr(argv[3]);
  //4>发送数据
  char buf[50];
  while(1)
  {
    bzero(buf,sizeof(buf));
    scanf("%s",buf);
    sendto(sfd,buf,strlen(buf),0,(struct sockaddr *)&other,sizeof(other));
  }
  close(sfd);
  return 0;
}

接收端代码案例如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc,char *argv[])
{
  if(argc<5)
  {
    printf("请输入<./可执行> <自己IP> <自己端口号> <目标IP> <目标端口号>\n");
    return -1;
  }
  //1>创建socket套接字
  int sfd;
  sfd = socket(AF_INET,SOCK_DGRAM,0);//注意换UDP类型
  if(sfd<0)
  {
    perror("socket");
    return -1;
  }
  //2>绑定自己的IP和端口号
  struct sockaddr_in myself;
  myself.sin_family = AF_INET;
  myself.sin_port = htons(atoi(argv[2]));  //8888
  myself.sin_addr.s_addr = inet_addr(argv[1]);
  if(bind(sfd,(struct sockaddr *)&myself,sizeof(myself))<0)
  {
    perror("bind");
    return -1;
  }
  //3>声明别人的IP和端口号
  struct sockaddr_in other;
  other.sin_family = AF_INET;
  other.sin_port = htons(atoi(argv[4]));  //9000
  other.sin_addr.s_addr = inet_addr(argv[3]);
  //4>接受数据
  char buf[50];
  int len = sizeof(other);
  while(1)
  {
    bzero(buf,sizeof(buf));
    recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&other,&len);
    printf("发送方说:%s\n",buf);
  }
  close(sfd);
  return 0;
} 

二、多路复用

前提讲述

IO阻塞和IO非阻塞

   int fcntl(int fd, int cmd, long arg); //改变文件描述符的特性

     int flag;

     flag = fcntl(sockfd, F_GETFL, 0);//F_GETFL获取文件描述符的特性

     flag |= O_NONBLOCK;//配置非阻塞

     fcntl(sockfd, F_SETFL, flag);//设置文件描述符特性为非阻塞

select

select
        int select(int nfds, fd_set *readfds, fd_set *writefds,
                fd_set *exceptfds, struct timeval *timeout);
        功能:就是将你要关心的文件描述符放入一个集合中,将这个集合交给内核判断,当集合中
                某个文件描述符被触发时,解除阻塞。        
        参数:
            nfds:最大文件描述符+1
            readfds:读集合
            writefds:写集合
            exceptfds:异常集合
            timeout:超时时间
        返回值:
            成功返回那个被触发的文件描述符
            失败,返回-1,并设置错误码
        struct timeval {
               long    tv_sec;         /* seconds */     秒
               long    tv_usec;        /* microseconds */ 微妙
           };    
           
           void FD_ZERO(fd_set *fdset)  清除文件描述符集合
            void FD_SET(int fd,fd_set *fdset)     将你要关心的文件描述符放入集合中
            void FD_CLR(int fd,fd_set *fdset)     将文件描述符移除集合
            int FD_ISSET(int fd,fd_set *fdset)     判断文件描述符是否在集合中
           
           fd_set是一个数据类型,本质是一个字节数组。长度为1024.
           readfds:读集合,往读集合放入我们关心的0,serfd描述符
           当select解除阻塞,说明这两个文件描述符有一个被触发了。
           一旦有文件描述符被触发,将移除集合中未触发的。再利用FD_ISSET去判断

             

poll

poll
        #include <poll.h>
        int poll(struct pollfd* fds, nfds_t nfds, int timeout)
        功能:
            多路复用,看哪个文件描述符就绪,做对应操作,看结构体第三参数是否被内核改变
        参数:
            fds:结构体数组,记
            nfds:要判断的文件描述符个数
            timeout:超时时间,0表示不阻塞;>0,阻塞的时间;默认设置为-1表示阻塞
        返回值:
            成功返回0
            失败返回-1,并设置错误码
        struct pollfd {
            int     fd;            // 委托内核检测的文件描述符                你希望监听文件描述符0  用户设置
            short   events;        // 委托内核检测文件描述符的什么事件        监听它被触发,也就是有数据可读POLLIN 用户设置
            short     revents     // 文件描述符实际发生的事件             内核设置
        }

三、图解如下


总结

关于C/C++网络编程基础知识超详细讲解第二部分的详解,懒大王就先分享到这里了,如果你认为这篇文章对你有帮助,请给懒大王点个赞点个关注吧,如果发现什么问题,欢迎评论区留言!!💕💕

相关文章
|
15天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
190 55
|
1月前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
81 2
|
25天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
130 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
11天前
|
数据采集 监控 安全
公司网络监控软件:Zig 语言底层优化保障系统高性能运行
在数字化时代,Zig 语言凭借出色的底层控制能力和高性能特性,为公司网络监控软件的优化提供了有力支持。从数据采集、连接管理到数据分析,Zig 语言确保系统高效稳定运行,精准处理海量网络数据,保障企业信息安全与业务连续性。
34 4
|
1月前
|
安全 Windows
【Azure Cloud Service】在Windows系统中抓取网络包 ( 不需要另外安全抓包工具)
通常,在生产环境中,为了保证系统环境的安全和纯粹,是不建议安装其它软件或排查工具(如果可以安装,也是需要走审批流程)。 本文将介绍一种,不用安装Wireshark / tcpdump 等工具,使用Windows系统自带的 netsh trace 命令来获取网络包的步骤
72 32
|
1月前
|
弹性计算 监控 数据库
制造企业ERP系统迁移至阿里云ECS的实例,详细介绍了从需求分析、数据迁移、应用部署、网络配置到性能优化的全过程
本文通过一个制造企业ERP系统迁移至阿里云ECS的实例,详细介绍了从需求分析、数据迁移、应用部署、网络配置到性能优化的全过程,展示了企业级应用上云的实践方法与显著优势,包括弹性计算资源、高可靠性、数据安全及降低维护成本等,为企业数字化转型提供参考。
61 5
|
1月前
|
存储 数据可视化 API
重磅干货,免费三方网络验证[用户系统+CDK]全套API接口分享教程。
本套网络验证系统提供全面的API接口,支持用户注册、登录、数据查询与修改、留言板管理等功能,适用于不想自建用户系统的APP开发者。系统还包含CDK管理功能,如生成、使用、查询和删除CDK等。支持高自定义性,包括20个自定义字段,满足不同需求。详细接口参数及示例请参考官方文档。
|
1月前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
38 1
|
1月前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
111 3
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
87 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络