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

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

前言

网络编程是指使用编程语言进行网络通信的过程。通过网络编程,计算机可以通过互联网或局域网与其他计算机进行数据交换和通信。在网络编程中,程序员需要使用特定的网络编程接口和协议(如TCP/IP、HTTP等)来实现数据的发送和接收。网络编程常用于开发网络应用、远程服务和分    布式系统等。

网络编程具有以下几个重要的作用:

  1. 数据交换和通信:通过网络编程,计算机可以在网络上进行数据的发送和接收,实现信息的交换和通信。这对于实现远程服务、分布式系统以及网络应用等都非常重要。
  2. 分布式系统:通过网络编程,可以将多台计算机连接起来,形成一个分布式系统。在分布式系统中,不同计算机之间可以互相通信和协作,共享资源和处理任务,从而提高系统的可靠性、性能和扩展性。
  3. 网络应用开发:网络编程是开发网络应用(如Web应用、聊天室、在线游戏等)的基础。通过网络编程,可以实现服务器端和客户端之间的数据交互,从而实现用户与服务器的交互和信息的展示。
  4. 网络安全:网络编程也与网络安全密切相关。通过网络编程,可以实现加密、认证、防止信息泄漏等安全机制,保护网络通信的隐私和安全。

总之,网络编程为计算机之间的数据交换和通信提供了技术基础,成为了构建分布式系统、开发网络应用以及保障网络安全的重要手段。


一、网络的含义与构成

含义:

  1.什么是网络?

       网络是信息传输、接收和共享的虚拟世界,通过把地球村内所有

信息汇聚起来,从而实现这些资源的共享。

       初衷:知识共享            

构成:

2.计算机上的软件层面的网络是由什么构成?

       1>IP

           格式:

               点分十进制        用户浏览与编写    192.168.10.x

               网络二进制        系统、电脑看的  0、1组合

           分类:

               IPv4   (主要集中,应用在电脑)

                   点分十进制        4个字节

                   网络二进制        32位

               (42个ip地址)

               IPv6  (手机WiFi、目前在电脑中不集中)

                   点分十进制        16个字节

                   网络二进制        128位

               IPv4分五类

                   A B C D E

               大型网 中大型 中小型 组播型 待用型

               

               

(1)A类地址

                   网络二进制:是以0开头

                   1个网络地址 3个主机地址(网络地址等于你在哪个教室,主机地址

                   代表你在教室中的位置)

网络二进制:

00000000 00000000 00000000 00000001 - 01111111 11111111 11111111 11111110

点分十进制:

   0.0.0.1-127.255.255.254  

注意:

       主机位全为0,定义为网段号,网络ID号

       主机位全为1,定义广播地址

       

(2) B类地址

                   网络二进制:是以10开头

                   2个网络地址 2个主机地址(网络地址等于你在哪个教室,主机地址

                   代表你在教室中的位置)

网络二进制:

10000000 00000000 00000000 00000001 - 10111111 11111111 11111111 11111110

点分十进制:

   128.0.0.1-191.255.255.254  

注意:

       主机位全为0,定义为网段号,网络ID号

       主机位全为1,定义广播地址

(3)C类地址

                   网络二进制:是以110开头

                   3个网络地址 1个主机地址(网络地址等于你在哪个教室,主机地址

                   代表你在教室中的位置)

网络二进制:

11000000 00000000 00000000 00000001 - 11011111 11111111 11111111 11111110

点分十进制:

   192.0.0.1-223.255.255.254  

注意:

       主机位全为0,定义为网段号,网络ID号

       主机位全为1,定义广播地址

(4)D类地址

                   网络二进制:是以1110开头

                   4个网络地址 0个主机地址(网络地址等于你在哪个教室,主机地址

                   代表你在教室中的位置)

网络二进制:

11100000 00000000 00000000 00000001 - 11101111 11111111 11111111 11111110

点分十进制:

   224.0.0.1-239.255.255.254    

注意:

       主机位全为0,定义为网段号,网络ID号

       主机位全为1,定义广播地址            

       

(5)E类地址

                   未来可期

       2>子网掩码

           网络地址全为1,主机全为0

           255.255.255.0

           用来判断是否在同一网段

           前缀长度:24(主要看子网掩码中1的个数)

           -->在linux网络配置中有体现

           

       3>默认网关

           主机地址默认值为1,随机取1-254,掐头去尾

           用来管理当前网段下的信息传输;网络的门户

           -->结合图片理解

           

       4>DNS域名解析服务器

           按照地方运营商提供的DNS域名服务器

           202.98.128.86

           www.baidu.com

           IP所属地:广东、深圳

二、网络的体系结构

1.OSI七层模型

ISO公司推出的网络体系模型

       

       协议:双方规定好的通信规则

           应用层

           表示层

           会话层

           传输层

           网络层

           数据链路层

           物理层

       

       目的:将数据封装起来,形成一个约定好的通信协议

       缺点:太复杂,太繁琐,有写功能重复

2.TCP/IP协议体系结构

       应用层        ftp、http、ping、ssh        

       传输层        TCP、UDP

       网络层        IP、ICMP、IGMP

       物理层        网线

       

       重点学习的网络体系结构,网络协议中的世界

3.数据经过体系结构,怎么封装?

封装数据的目的是为了保证数据在网络中传输的稳定性

           -->结合图片理解

4.端口号

区分不同的应用程序,针对主机

           QQ4999,微信5050

           2个字节 0~65535

           0~1023  --》系统进程使用的

           1024~65535  --》用户用的

5.大小端

不同类型的CPU的主机中,内存存储的整数字节序有两种

           小端序:

               低位字节存储到低位地址,     linux

           大端序:

               低位字节存储到高位地址,     系统

6.TCP/UDP传输层的协议

   TCP/UDP的区别:

       UDP(用户数据报协议)的特点:只管发送,没有连接属性,数据因此不可靠,不稳定,易丢失。

       举例:写信

       

       TCP(传输控制协议)的特点:要先建立连接,保证了数据的可靠信,因此数据稳定,不丢包。

       举例:带电话

三、系统函数API学习框架(TCP)    

服务器(优先):

    框架:            

               1>创建socket套接字

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

               3>监听

               4>等待客户端连接

               5>数据收/发

               6>关闭套接字(具有网路属性的文件描述符)

1.创建socket套接字socket

  头文件:

   #include<sys/types.h>

   #include<sys/socket.h>

   int socket(int domain, int type, int protocol);

   功能:

       创建一个具有网络属性的文件描述符

   参数:

       domain:协议族

           AF_UNIX,AF_LOCAL          本地连接

           AF_INET                   IPv4

           AF_INET6                   IPv6

       type:

       SOCK_STREAM    流式套接字       TCP

       SOCK_DGRAM  数据报套接字   UDP

       SOCK_RAW    原始套接字

       protocol:

           默认为0,表示前面两个所选参数生效

   返回值:

       成功返回具有网络属性的文件描述符

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

       

   socket位于哪里,位于应用层和传输层之间

2.绑定自己的IP地址和端口号(bind

 

头文件:
    #include<sys/types.h>
    #include<sys/socket.h>
    int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
    功能:
        将IP地址和端口号绑定在sockfd上,难点在于第二参结构体赋值
    参数:
        sockfd:这个是socket创建出来的具有网络属性的文件描述符
        my_addr:结构体指针,用来赋值IP地址和端口号
        addrlen:结构体的长度
    返回值:
        成功返回0
        失败,返回-1并设置错误码
    
    第二参数const struct sockaddr *my_addr
    
    struct sockaddr {
       sa_family_t sa_family;  2个字节
       char        sa_data[14]; 14个字节
    }

   问题:

       赋值时IP地址和端口号哪个在前哪个在后不确定

       IP地址和端口号只占据6个字节,还有8个字节怎么填充

       

   因此选用同族结构体

 

struct sockaddr_in{
        sa_family_t   sin_family;   //地址族
        uint16_t      sin_port;     //端口号 
        struct in_addr    sin_addr;  //32位IP地址
        char     sin_zero[8];      //预留未使用,自动填充0
    };
    struct in_addr{
        In_addr_t  s_addr;    //32位IPv4地址
    };

   1>注意端口大小端序转换的问题

   #include <arpa/inet.h>

   

   uint32_t htonl(uint32_t hostlong);  32位

   uint16_t htons(uint16_t hostshort); 16位

   以上小端序转大端序

   

   uint32_t ntohl(uint32_t netlong);

   uint16_t ntohs(uint16_t netshort);

   大端序转回小端序

   2>注意IP格式转换

   #include <netinet/in.h>

   in_addr_t inet_addr(const char *cp);

   将点分十进制的IP地址转换为网络二进制

   

   char *inet_ntoa(struct in_addr in);

   将网络二进制转回点分十进制

3.监听listen

   头文件:

   #include <sys/types.h>

   #include <sys/socket.h>

   int listen(int sockfd, int backlog);

   功能:

       保护服务器,限制同一瞬间最大的客户端连接数量

   参数:

       sockfd:这个是socket创建出来的具有网络属性的文件描述符

       backlog:最大的客户端连接数量

   返回值:

       成功返回0

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

4.等待客户端连接 (等待意味着“阻塞” accept)

  头文件:

   #include <sys/types.h>

   #include <sys/socket.h>

   int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

   功能:

       等待客户端连接,第二参能保存对方的IP地址和端口号,不需要保存对方设置NULL

   参数:

       sockfd:这个是socket创建出来的具有网络属性的文件描述符

       addr:用来保存客户端信息的结构体

       addrlen:结构体长度。

   返回值:

       成功返回与客户端通信的文件描述符,与socket函数类似

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

客户端:

为了演示效果明显,我们开始写客户端框架

       1>创建socket套接字

       2>声明服务器所在的IP地址和端口号

       3>主动连接服务器

       4>数据收/发

       5>关闭文件描述符

1.创建socket套接字与服务器相似

2.声明服务器所在的IP地址和端口号

       struct sockaddr_in server;

       server.sin_family = AF_INET;

       server.sin_port = htons(8888);

       server.sin_addr.s_addr = inet_addr("192.168.10.5");

       注意声明都是别人的,与你无关

3.主动连接服务器connect

   头文件:

   #include <sys/types.h>

   #include <sys/socket.h>

   int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen)

   功能:

       主动连接服务器,第二参能保存对方的IP地址和端口号,不需要设置NULL

   参数:

       sockfd:这个是socket创建出来的具有网络属性的文件描述符

       addr:用来连接服务器的结构体

       addrlen:结构体长度,一般用sizeof()。

   返回值:

       成功返回0

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

4.数据发送(send

   头文件:

   #include <sys/types.h>

   #include <sys/socket.h>

 

   ssize_t send(int sockfd, const void *buf, size_t len, int flags);

   功能:

       数据发送

   参数:

       sockfd:套接字文件描述符

       buf:发送缓冲区

       len:发送缓冲区长度

       flags:默认为0,表示阻塞

   返回值:

   成功:返回发送的字节数

   失败:返回-1,并设置errno

5.数据接收(recv

  头文件:

   #include <sys/types.h>

   #include <sys/socket.h>

   ssize_t recv(int sockfd,void *buf, size_t len, int flags);

   功能:

       数据接收

   参数:

       sockfd:套接字文件描述符

       buf:接收缓冲区

       len:接收缓冲区长度

       flags:默认为0,表示阻塞

   返回值:

   >0: 返回接收的字节数

   =0:    客户端异常退出(CTRL+C)

   <0: 失败:返回-1,并设置errno

四、服务器和客户端代码实例

//服务器代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
 
int main(void)
{
  //1>创建socket套接字
  int serfd = socket(AF_INET,SOCK_STREAM,0);//1.选IPv4,2选TCP,3默认0
  if(serfd<0) //错误判断
  {
    perror("socket");
    return -1;
  }
  printf("创建出的socket的值为%d\n",serfd);
  //2>绑定自己的IP地址和端口号
  struct sockaddr_in my_addr;
  my_addr.sin_family = AF_INET;//IPv4
  my_addr.sin_port = htons(8888);//将linux小端转系统的大端
  my_addr.sin_addr.s_addr =inet_addr("192.168.10.5");//注意将IP地址格式转为网络二进制,还有记得改成自己的linuxIP地址
  int ret;
  ret = bind(serfd,(struct sockaddr *)&my_addr,sizeof(my_addr));
  //第二参将同族结构体强转为函数需要的结构体类型
  if(ret<0) //错误判断
  {
    perror("bind");
    return -1;
  }
  printf("serfd网络属性已成功配置!\n");
  //3>监听
  ret = listen(serfd,8);
  if(ret<0) //错误判断
  {
    perror("listen");
    return -1;
  }
  printf("监听已启动,保护服务器中^-^\n");
  //4>等待客户端连接 阻塞
  int clifd = accept(serfd,NULL,NULL);//accept接触阻塞后将产生一个与客户端通信的文件描述符
  if(clifd<0) //错误判断
  {
    perror("accept");
    return -1;
  }
  printf("创建出与客户端通信的文件描述符值为%d\n",clifd);
  printf("有客户连接进来了!\n");
  //5>数据的接收
  char buf[30];
  while(1)
  {
#if 0
    bzero(buf,sizeof(buf));
    ret = recv(clifd,buf,sizeof(buf),0);//阻塞
    printf("客户端说:%s\n",buf);
#endif
    bzero(buf,sizeof(buf));
    ret = recv(clifd,buf,sizeof(buf),0);//阻塞
    if(ret<0)
    {
      perror("recv");
      return -1;
    }else if(ret == 0)
     {
       printf("客户带着小姨子跑了!\n");
       return -1;
     }else
      {
      printf("客户端说:%s\n",buf);
      }
  }
  //6>关闭套接字
  close(serfd);
  close(clifd);
  return 0;
}
//客户端代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
 
int main(void)
{
  //1>创建socket套接字
  int sockfd = socket(AF_INET,SOCK_STREAM,0);
  if(sockfd<0)
  {
    perror("socket");
    return -1;
  }
  printf("创建出的socket的值为%d\n",sockfd);
  //2>声明"服务器"所在的IP地址和端口号
  struct sockaddr_in server;
  server.sin_family = AF_INET;
  server.sin_port = htons(8888);
  server.sin_addr.s_addr = inet_addr("192.168.10.5");
  printf("已经声明服务器的IP地址和端口号!\n");
  //3>主动连接服务器
  int ret = connect(sockfd,(struct sockaddr*)&server,sizeof(server));
  if(ret<0)
  {
    perror("connect");
    return -1;
  }
  printf("连接服务器成功,请进行操作!\n");
  //4>数据发送
  char buf[30];
  while(1)
  {
    bzero(buf,sizeof(buf));
    scanf("%s",buf);
    send(sockfd,buf,strlen(buf),0); 
  }
  
  //5>关闭文件描述符
  close(sockfd);
  return 0;
}


总结

       本篇文章针对C/C++ 网络编程进行详细讲解,希望能够帮到大家!

       以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

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