【网络编程基础(一)】网络基础和SOCKET

1、网络三要素

  • ip地址:在网络确定另一个交互数据的计算机位置
  • 端口号:确定计算机中某一个应用程序 10000以下不适用(系统使用,如热点,蓝牙等)
  • 通信协议:通信规则

2、IPV4和IPV6区别

IPv4和IPv6是互联网协议(Internet Protocol)的个版本,它们有以下几点区别:

  1. 地址长度:IPv4使用32位地址,而IPv6使用128位地址。
  2. 地址表示:IPv4地址使用点分十进制表示,例如192.168.0.1。而IPv6地址使用冒号分隔的八组四位十六进制数表示,(数字+字母 大小写排列组合)
    例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334。
  3. 地址数量:IPv4最多可以提供约42亿个地址,而IPv6可以提供约340万亿亿亿亿(3.4×10^38)个地址。
  4. 自动配置:IPv6支持自动配置,设备可以根据网络环境自动获取IPv6地址和其他网络配置信息。而IPv4需要手动配置或使用DHCP协议进行地址分配。
  5. 安全性:IPv6在设计时考虑了更强的安全性,支持IPsec(Internet Protocol Security)协议,可以提供端到端的数据加密和认证功能。而IPv4需要额外的安全协议来实现类似的功能。
  6. 兼容性:由于IPv6与IPv4有很大的差异,为了实现平滑过渡,IPv6引入了双协议栈机制,可以同时支持IPv4和IPv6。这样可以保证在IPv6逐渐普及的过程中,与IPv4兼容的设备仍然可以正常访问互联网。

3、网络交互

3.1、交互模型图

在这里插入图片描述

3.2、基础通信协议

在这里插入图片描述
** TCP和UDP区别:**

TCP:更加安全,效率低一些
UDP:效率更高,安全性不足

3.3、OSI参考模型与TCP/IP参考模型对应关系

在这里插入图片描述

应用层 :HTTP,FTP,SNMP等
表示层 :ASCII、PICT、TIFF、JPEG、 MIDI、MPEG
会话层 :RPC、SQL、NFS 、X WINDOWS、ASP
传输层 :TCP、UDP=
网络层 :IP、IPX、APPLETALK、ICMP
数据链路层: 802.2、802.3ATM
物理层

4、SOCKET网络套接字

4.1、SOCKET分类

  • 流式套接字(SOCK_STREAM)
    流式的套接字可以提供可靠的、面向连接的通讯流。它使用了TCP协议。TCP 保证了数据传输的正确性和顺序性。
  • 数据报套接字(SOCK_DGRAM)
    数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。使用数据报协议UDP协议。
  • 原始套接字。
    原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等。

4.2、基于流式套接字的编程流程

在这里插入图片描述

4.3、网络通信雏形

在这里插入图片描述

注:socket在IPC技术之一:不同电脑中的两个进程间的通信

4.4、socket函数

在这里插入图片描述

  • 参数1:协议族 (IPV4/IPV6)
  • 参数2:网络类型(TCP/UDP)
  • 参数3:一般为0
  • 返回值:返回新建的网络通道描述符
  • 函数功能:网络初始化,验证当前系统是否可以使用网络

协议族
在这里插入图片描述
网络类型
在这里插入图片描述

4.4.1、socket函数示例

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>]
#include <stdio.h>
using namespace std;
int main()
{
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(socketfd<0)
	{
		perror("socket error");
	}
	return 0;
}

4.5、bind函数

在这里插入图片描述
参数1:网络通道描述符(socket函数返回值)
参数2:绑定的IP地址和端口号的结构体
参数3:绑定的IP地址和端口号的结构体的大小
函数功能:绑定端口号和IP地址
返回值:成功返回0,失败返回-1

4.5.1、bing函数示例

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>]
#include <netinet/in.h>
#include <stdio.h>
using namespace std;
int main()
{
	int len;
	struct sockaddr_in addr;
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(socketfd<0)
	{
		perror("socket error");
	}
	else
	{
		
		cout << "服务器网络初始化 socketfd " << socketfd << endl;
		//协议族
		addr.sin_family = AF_INET;
		//绑定的是服务器自己的IP地址,INADDR_ANY通过系统获取可用的网络IP
		addr.sin_addr.s_addr = INADDR_ANY;
		//绑定服务器自己的端口号
		addr.sin_port = htons(10001);
		len = sizeof(addr);
		//绑定端口号和IP地址
		//参数2:需要强制转换类型
		if (bind(socketfd, (struct sockaddr*)&addr, len) == -1)
		{
			perror("bind error");
			return 0;
		}
	}
	return 0;
}

4.6、listen函数

在这里插入图片描述
参数1:网络通道描述符(socket函数返回值)
参数2:客户端数量
函数功能:监听网络是否有数据过来
返回值:成功返回0,失败返回-1

4.6.1、listen函数示例

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>]
#include <netinet/in.h>
#include <stdio.h>
using namespace std;
int main()
{
	int len;
	struct sockaddr_in addr;
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(socketfd<0)
	{
		perror("socket error");
		return 0;
	}
	else
	{
		
		cout << "服务器网络初始化 socketfd " << socketfd << endl;
		//协议族
		addr.sin_family = AF_INET;
		//绑定的是服务器自己的IP地址,INADDR_ANY通过系统获取可用的网络IP
		addr.sin_addr.s_addr = INADDR_ANY;
		//绑定服务器自己的端口号
		addr.sin_port = htons(10001);
		len = sizeof(addr);
		//绑定端口号和IP地址
		//参数2:需要强制转换类型
		if (bind(socketfd, (struct sockaddr*)&addr, len) == -1)
		{
			perror("bind error");
			return 0;
		}
		//监听网络是否有数据过来
		if (listen(socketfd, 10) == -1)//10为客户端数量
		{
			perror("listen error");
			return 0;
		}
		cout << "服务器网络搭建成功" << endl;
	}
	return 0;
}

4.7、accept函数

在这里插入图片描述
参数1:网络通道描述符(socket函数返回值)
参数2:在上一步操作中已经完成,所以为NULL(绑定IP地址和端口号)
参数3:同上
返回值是表示已连接的套接字描述符

accept 函数由 TCP 服务器调用,用于从已完成连接队列队头返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠。
参数sockfdsockfd是socket系统调用返回的服务器端socket描述符addr用来返回已连接的对端(客户端)的协议地址

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>]
#include <netinet/in.h>
#include <stdio.h>
using namespace std;
int main()
{
	int len=0;
	int acceptfd=0;
	struct sockaddr_in addr;
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(socketfd<0)
	{
		perror("socket error");
		return 0;
	}
	else
	{
		
		cout << "服务器网络初始化 socketfd " << socketfd << endl;
		//协议族
		addr.sin_family = AF_INET;
		//绑定的是服务器自己的IP地址,INADDR_ANY通过系统获取可用的网络IP
		addr.sin_addr.s_addr = INADDR_ANY;
		//绑定服务器自己的端口号
		addr.sin_port = htons(10001);
		len = sizeof(addr);
		//绑定端口号和IP地址
		//参数2:需要强制转换类型
		if (bind(socketfd, (struct sockaddr*)&addr, len) == -1)
		{
			perror("bind error");
			return 0;
		}
		//监听网络是否有数据过来
		if (listen(socketfd, 10) == -1)//10为客户端数量
		{
			perror("listen error");
			return 0;
		}
		cout << "服务器网络搭建成功" << endl;
		while (1)
		{
			//等待客户端连接   acceptfd 代表已经连接成功的客户端 
			acceptfd=accept(socketfd,NULL,NULL);//阻塞函数  
			cout << "客户端连接成功 acceptfd =" << acceptfd << endl;
		}
	}
	return 0;
}

4.8、connect函数

在这里插入图片描述
参数1:网络通道描述符(socket函数返回值)
参数2:绑定的IP地址和端口号的结构体
参数3:绑定的IP地址和端口号的结构体的大小

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>]
#include <netinet/in.h>
#include <stdio.h>
using namespace std;
int main()
{
	int len=0;
	struct sockaddr_in addr;
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(socketfd<0)
	{
		perror("socket error");
		return 0;
	}
	else
	{
		cout << "服务器网络初始化 socketfd " << socketfd << endl;

		addr.sin_family = AF_INET;
		//绑定服务器IP地址   表示客户端主动查找服务器IP连接
		addr.sin_addr.s_addr = inet_addr("192.168.16.229");
		//绑定服务器自己的端口号
		addr.sin_port = htons(10001);
		len = sizeof(addr);
		if(connect(socketfd,(struct sockaddr*)&addr,len)==-1)
		{
			perror("socket error");
			return 0;
		}
	}
	return 0;
}

5、客户端服务器通信示例

5.1、客户端示例

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main()
{
	int res = 0;
	char buf[100] = { 0 };
	int len = 0;
	struct sockaddr_in addr;
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET, SOCK_STREAM,0);
	if (socketfd < 0)
	{
		perror("socket error");
		return 0;
	}
	else
	{
		cout << "服务器网络初始化 socketfd " << socketfd << endl;

		addr.sin_family = AF_INET;
		//绑定服务器IP地址   表示客户端主动查找服务器IP连接
		addr.sin_addr.s_addr = inet_addr("192.168.13.129");
		//绑定服务器自己的端口号
		addr.sin_port = htons(10001);
		len = sizeof(addr);
		if (connect(socketfd, (struct sockaddr*)&addr, len) == -1)
		{
			perror("socket error");
			return 0;
		}
		while (1)
		{
			cin >> buf;
			res = write(socketfd, buf, sizeof(buf));
			cout << "res= " << res << endl;
		}
	}
	return 0;
}

5.2、服务器示例

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
using namespace std;
int main()
{
	char buf[100]={0};
	pid_t pid =0;
	int res=0;
	int len=0;
	int acceptfd=0;
	struct sockaddr_in addr;
	//网络初始化,验证当前系统是否可以使用网络
	int socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(socketfd<0)
	{
		perror("socket error");
		return 0;
	}
	else
	{
		cout << "服务器网络初始化 socketfd " << socketfd << endl;
		//协议族
		addr.sin_family = AF_INET;
		//绑定的是服务器自己的IP地址,INADDR_ANY通过系统获取可用的网络IP
		addr.sin_addr.s_addr = INADDR_ANY;
		//绑定服务器自己的端口号
		addr.sin_port = htons(10001);
		len = sizeof(addr);
		//绑定端口号和IP地址
		//参数2:需要强制转换类型
		if (bind(socketfd, (struct sockaddr*)&addr, len) == -1)
		{
			perror("bind error");
			return 0;
		}
		//监听网络是否有数据过来
		if (listen(socketfd, 10) == -1)//10为客户端数量
		{
			perror("listen error");
			return 0;
		}
		cout << "服务器网络搭建成功" << endl;
		while (1)
		{
			//等待客户端连接   acceptfd 代表已经连接成功的客户端 
			acceptfd=accept(socketfd,NULL,NULL);//阻塞函数  
			cout << "客户端连接成功 acceptfd =" << acceptfd << endl;
			
			pid =fork();
			if(pid ==0)
			{
				while(1)
				{
					res= read(acceptfd,buf,sizeof(buf));
					cout<<"服务器res="<<res<<"buf = "<<buf<<endl;
				}
			}
		}
	}
	return 0;
}

5.3、网络通信示图

在这里插入图片描述

相关推荐

  1. linux socket网络编程基础知识

    2024-03-17 00:16:03       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-17 00:16:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-17 00:16:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-17 00:16:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-17 00:16:03       18 阅读

热门阅读

  1. 由浅到深认识C语言(1):C语言概论

    2024-03-17 00:16:03       20 阅读
  2. app分发步骤有那些?

    2024-03-17 00:16:03       21 阅读
  3. 如何理解闭包

    2024-03-17 00:16:03       22 阅读
  4. 【Unity】旋转的尽头是使用四元数让物体旋转

    2024-03-17 00:16:03       16 阅读
  5. Websocket服务监听收发消息

    2024-03-17 00:16:03       21 阅读
  6. Meson编译工具安装及使用Meson编译DPDK

    2024-03-17 00:16:03       23 阅读
  7. WSL与VirtualBox区别

    2024-03-17 00:16:03       21 阅读
  8. CentOS8安装docker

    2024-03-17 00:16:03       15 阅读
  9. docker部署zabbix使用postgresql数据库

    2024-03-17 00:16:03       19 阅读
  10. C语言演示多线程编程条件下自旋锁和屏障的使用

    2024-03-17 00:16:03       17 阅读
  11. 使用docker搭建Komga

    2024-03-17 00:16:03       20 阅读
  12. Docker 容器和 Kubernetes 退出码 —— 筑梦之路

    2024-03-17 00:16:03       16 阅读
  13. CCF 202009-3 点亮数字人生(拓扑排序)

    2024-03-17 00:16:03       19 阅读