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

马肤

温馨提示:这篇文章已超过381天没有更新,请注意相关的内容是否还可用!

摘要:本篇文章是关于C/C++网络编程基础知识的超详细讲解的第一部分,涵盖了系统性学习的第11天内容。文章从基础知识出发,逐步深入,包括网络编程的基本概念、TCP/IP协议、套接字编程、网络数据通信等核心内容。文章旨在帮助读者掌握网络编程的基本技能,为后续的复杂网络应用开发打下坚实的基础。

目录

前言

一、网络的含义与构成

含义:

构成: 

二、网络的体系结构

1>OSI七层模型

2>TCP/IP协议体系结构 

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

4>端口号

5>大小端序

6>TCP/UDP传输层的协议 

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

服务器(优先):

 客户端:

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

总结


前言

网络编程是指使用编程语言进行网络通信的过程。通过网络编程,计算机可以通过互联网或局域网与其他计算机进行数据交换和通信。在网络编程中,程序员需要使用特定的网络编程接口和协议(如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

    #include

    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

    #include

    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

    

    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

    in_addr_t inet_addr(const char *cp);

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

    

    char *inet_ntoa(struct in_addr in);

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

3.监听 (listen)

    头文件:

    #include

    #include

    int listen(int sockfd, int backlog);

    功能:

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

    参数:

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

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

    返回值:

        成功返回0

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

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

   头文件:

    #include

    #include

    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

    #include

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

    功能:

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

    参数:

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

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

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

    返回值:

        成功返回0

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

 4.数据发送(send)

    头文件:

    #include

    #include

 

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

    功能:

        数据发送

    参数:

        sockfd:套接字文件描述符

        buf:发送缓冲区

        len:发送缓冲区长度

        flags:默认为0,表示阻塞

    返回值:

    成功:返回发送的字节数

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

 5.数据接收(recv)

   头文件:

    #include

    #include

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

    功能:

        数据接收

    参数:

        sockfd:套接字文件描述符

        buf:接收缓冲区

        len:接收缓冲区长度

        flags:默认为0,表示阻塞

    返回值:

    >0: 返回接收的字节数

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

    创建socket套接字 int serfd = socket(AF_INET,SOCK_STREAM,0);//1.选IPv4,2选TCP,3默认0 if(serfd绑定自己的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监听 ret = listen(serfd,8); if(ret等待客户端连接 阻塞 int clifd = accept(serfd,NULL,NULL);//accept接触阻塞后将产生一个与客户端通信的文件描述符 if(clifd数据的接收 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关闭套接字 close(serfd); close(clifd); return 0; }

//客户端代码
#include 
#include 
#include 
#include 
#include 
#include 
int main(void)
{
	//1>创建socket套接字
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd声明"服务器"所在的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数据发送
	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语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!  


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码