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语言的其他重要的基础知识,感谢大家支持懒大王!

相关文章
|
3天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
15 2
|
1月前
|
机器学习/深度学习 数据采集 人工智能
未来的守护神:AI驱动的网络安全之盾,如何用智慧的光芒驱散网络黑暗势力?揭秘高科技防御系统背后的惊天秘密!
【10月更文挑战第3天】随着网络技术的发展,网络安全问题日益严峻,传统防御手段已显不足。本文探讨了构建AI驱动的自适应网络安全防御系统的必要性及其关键环节:数据采集、行为分析、威胁识别、响应决策和执行。通过Python库(如scapy、scikit-learn和TensorFlow)的应用实例,展示了如何利用AI技术提升网络安全防护水平。这种系统能够实时监控、智能分析并自动化响应,显著提高防护效率与准确性,为数字世界提供更强大的安全保障。
60 2
|
17天前
|
监控 安全 测试技术
网络信息系统的整个生命周期
网络信息系统规划、设计、集成与实现、运行维护及废弃各阶段介绍。从企业需求出发,经过可行性研究和技术评估,详细设计系统架构,完成设备安装调试和系统集成测试,确保稳定运行,最终安全退役。
31 1
网络信息系统的整个生命周期
|
3天前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
20 3
|
4天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
21 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
17天前
|
机器学习/深度学习 存储 运维
图神经网络在复杂系统中的应用
图神经网络(Graph Neural Networks, GNNs)是一类专门处理图结构数据的深度学习模型,近年来在复杂系统的研究和应用中展现了强大的潜力。复杂系统通常涉及多个相互关联的组件,其行为和特性难以通过传统方法进行建模和分析。
40 3
|
17天前
|
编解码 安全 Linux
网络空间安全之一个WH的超前沿全栈技术深入学习之路(10-2):保姆级别教会你如何搭建白帽黑客渗透测试系统环境Kali——Liinux-Debian:就怕你学成黑客啦!)作者——LJS
保姆级别教会你如何搭建白帽黑客渗透测试系统环境Kali以及常见的报错及对应解决方案、常用Kali功能简便化以及详解如何具体实现
|
21天前
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
|
1月前
|
域名解析 缓存 网络协议
【网络】DNS,域名解析系统
【网络】DNS,域名解析系统
96 1
|
1月前
|
物联网 5G 调度