这里写目录标题
- 1、网络三要素
- 2、IPV4和IPV6区别
- 3、网络交互
- 3.1、交互模型图
- 3.2、基础通信协议
- 3.3、OSI参考模型与TCP/IP参考模型对应关系
- 4、SOCKET网络套接字
- 4.1、SOCKET分类
- 4.2、基于流式套接字的编程流程
- 4.3、网络通信雏形
- 4.4、socket函数
- 4.4.1、socket函数示例
- 4.5、bind函数
- 4.5.1、bing函数示例
- 4.6、listen函数
- 4.6.1、listen函数示例
- 4.7、accept函数
- 4.8、connect函数
- 5、客户端服务器通信示例
- 5.1、客户端示例
- 5.2、服务器示例
- 5.3、网络通信示图
1、网络三要素
- ip地址:在网络确定另一个交互数据的计算机位置
- 端口号:确定计算机中某一个应用程序 10000以下不适用(系统使用,如热点,蓝牙等)
- 通信协议:通信规则
2、IPV4和IPV6区别
IPv4和IPv6是互联网协议(Internet Protocol)的个版本,它们有以下几点区别:
- 地址长度:IPv4使用32位地址,而IPv6使用128位地址。
- 地址表示:IPv4地址使用点分十进制表示,例如192.168.0.1。而IPv6地址使用冒号分隔的八组四位十六进制数表示,(数字+字母 大小写排列组合)
例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334。 - 地址数量:IPv4最多可以提供约42亿个地址,而IPv6可以提供约340万亿亿亿亿(3.4×10^38)个地址。
- 自动配置:IPv6支持自动配置,设备可以根据网络环境自动获取IPv6地址和其他网络配置信息。而IPv4需要手动配置或使用DHCP协议进行地址分配。
- 安全性:IPv6在设计时考虑了更强的安全性,支持IPsec(Internet Protocol Security)协议,可以提供端到端的数据加密和认证功能。而IPv4需要额外的安全协议来实现类似的功能。
- 兼容性:由于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;
}