① 什么是IP地址
IP地址:是计算机在网络中唯一的标识,由两部分组成
分别是表示网络区域的网络号,和该网络下的主机编号
网络号:确定计算机所从属于哪个局域网络
主机号:计算机在该局域网络下的一个编号
② IP的划分,有几类IP地址
五类IP地址
A类IP地址 1.0.0.0——————255.255.255.255 已经保留不在供给
B类网络 128.0.0.0————191.255.255.255 名地址,网管中心
C类网络 192.0.0.0————223.255.255.255 校园网或者企业网,家庭网
D类网络 224.0.0.0————239.255.255.255 组播IP
E类网络 240.0.0.0————255.255.255.255 保留或实验室使用
③ IP地址中200.0.0.0这个IP属于哪一类网络?
C类网络,C类网络从192.0.0.0——————223.255.255.255
④ 什么是端口号,端口号的作用?
主机号是为了区分同一主机上的多个进程
使用端口号来进行处理。端口号是一个无符号的2字节的整数
取值范围为[0 -65535] 2^16-1
其中[0 ——1023] 号端口号编程是不适用,已经被占用
可以使用的是[1024 --49151]
[49152 --65535]号端口号是临时端口号,这部分是客户端运行时动态选择的
⑤ 对字节序的理解
字节序引入主要是因为不同计算机架构选择了不同的存储方式
主机字节序,存储多字节整数,主机字节序分为大端存储和小端存储
网络字节序,存储多字节整数,是大端存储
通过函数可以实现主机字节序和网络字节序之间的相互转换。
主机字节序决定了数据在主机内存中的排列方式,
对于主机内部的数据处理至关重要;而网络字节序
则确保了不同系统之间的通信能够正常进行,
通过统一的字节序规则,实现了数据的正确传输和解析
⑥ 7层网络体系结构
应用层 会话层 表示层 传输层
网络层 数据链路层 物理层
⑦ TCP和UDP 通信的区别
相同:同属于传输层的协议TCP:----->稳定 传输控制协议
TCP的优点
1》提供面向连接的,可靠的数据传输协议
2>> 传输过程中,数据无误,数据无丢失,无失去顺序,数据无重复
3>> 每个数据都需要数据应答包,若没有应答,会一直重复上面的包发送直到正确为止
缺点:
4>>数据传输效率地低,耗费资源多
5>>缺点:数据的收发不是同步的,
(1)为了提高效率, TCP会将多个较小,并且发送间隔短的数据包粘成一个数据包发送。
(2)粘包算法称之为 Nagle算法
6>>TCP的使用场景 对传输质量要求高,以及传输达礼郎数据的通信,在需要可靠通信的场合 (如账号登录,大型文件下载)
UDP ----->快速 用户数据报协议
优点:1 传输速度快,实时性高
2 收发是同步的,不需要粘包
缺点: 3 面向无连接的,不保证数据可靠性,尽最大能力传输,
4传输过程中不保证数据的丢失,重复,失序等现象
5限制每次传输数据的大小,超出部分直接忽略删除
6》》适用场景:广播,通讯软件等
⑧ TCP通信过程中,服务器端实现的流程
<1>socket 函数创建一个用于连接的套接字文件描述符
<2>bind 函数绑定IP和端口号
<3>listen函数将套接字设置为被动监听模式,准备接收客户请求
TCP服务端
int main(int argc, const char *argv[]){//1 为通信创建一个端点int sfd=socket(AF_INET,SOCK_STREAM,0);//参数1 说明使用的是IPv4网络//参数2 说明使用的是TCP面向连接的通讯方式//参数3,由于参数2已经指定通信方式,直接为0if(sfd ==-1){perror("socket error");return -1;}printf("socket success sfd=%d\n",sfd); // 3 (0 stdin ,stdout 1,stderr 2)// 2 绑定IP地址和端口号// 2.1 准备地址信息结构体struct sockaddr_in sin;sin.sin_family =AF_INET;sin.sin_port =htons(SER_PORT);sin.sin_addr.s_addr =inet_addr(SER_IP);//嵌入一个小的结构体//绑定工作if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))){perror("bind error");return -1;}printf("bind success\n");// 3 将套接字设置成被动监听状态;//if(listen(sfd,128)==-1){perror("listen error");return -1;}printf("listen success\n");// 4 阻塞等待客户端的连接// 4.1 定义用于接受客户端信息的容器struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);int newfd =accept(sfd,(struct sockaddr*)&cin,&addrlen);if(newfd ==-1){perror("accept error");return -1;}printf("accept success\n");printf("[%s %d]发送来连接请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));// 5 与客户端进行相互通信char rbuf[128]={}; //用于读取消息内容的容器while(1){// 清空容器bzero(rbuf,sizeof(rbuf));//从套接字读取数据int res =read(newfd,rbuf,sizeof(rbuf));if(res == 0){printf("客户端已经下线\n");break ;}//将读取到的消息展示出来printf("[%s %d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf );//将收到的消息处理一下,回复给客户端strcat(rbuf,"OK");//将消息发送给客户端write(newfd,rbuf,strlen(rbuf));printf("发送成功\n");}// 6 关闭套接字close(sfd);return 0;}
TCP客户端
// TCP 通信客户端实现 server-side 服务端 client-side 客户端 端口号 port number int main(int argc, const char *argv[])
{//1 创建用于通信的套接字文件描述符int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd == -1){perror("socket error");return -1;}printf("socket success cfd =%d\n",cfd);//2 绑定IP地址和端口 对于客户端可以不必要绑定IP地址和端口 //2.1 填充客户端地址信息结构体struct sockaddr_in cin;cin.sin_family =AF_INET;cin.sin_port =htons(CLI_PORT);cin.sin_addr.s_addr =(inet_addr(CLI_IP));//2.2 绑定if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin))== -1){perror("bind error");return -1;}printf("bind success\n");// 3.1 准备对端(对面)地址信息结构体struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port =htons(SER_PORT);sin.sin_addr.s_addr =inet_addr(SER_IP);//3.2连接服务器if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){ perror("connect error");return -1;}printf("connect success\n");//4 数据收发//char wbuf[128]="";char rbuf[128]="";while(1){//从终端上获取要发送的数据fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;printf("发送成功\n");//接收服务器发来的消息//bzero(rbuf,sizeof(rbuf));printf("服务器发来的消息为:%s\n",rbuf);}//关闭套接字close(cfd);return 0;
}
UDP服务端
#include <myheader.h>#define SER_PORT 8888#define SER_IP "192.168.230.128"int main(int argc, const char *argv[]){/* ****server-side **** *///创建用于通信的套接字文件描述符 sfd -->service file descriptor 服务文件描述符int sfd =socket(AF_INET,SOCK_DGRAM,0);if(sfd == -1){perror("socket error");return -1;}printf("sfd=%d\n",sfd);//绑定IP地址和端口号// 2.1 填充地址信息结构体struct sockaddr_in sin;sin.sin_family =AF_INET;sin.sin_port =htons(SER_PORT);sin.sin_addr.s_addr =inet_addr(SER_IP);// 2.2 绑定if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin) )== -1){perror("bind erroe");return -1;}// 3 数据收发char rbuf[128]="";//准备接收对端的地址信息struct sockaddr_in cin;socklen_t addrlen =sizeof(cin);while(1){//清空容器bzero (rbuf,sizeof(rbuf));//读取数据//recvfrom(sfd,rbuf,sizeof(rbuf),0,(struct sockaddr*)&cin,&addrlen);printf("收到的消息为:%s\n",rbuf);//将收到的消息加上一个OKK回复过去strcat(rbuf,"OKK");if(sendto (sfd,rbuf,strlen(rbuf),0,(struct sockaddr*)&cin,sizeof(cin) == -1)){perror("sendto error");return -1;}printf("发送成功\n");}close(sfd);return 0;}
UDP客户端
int main(int argc, const char *argv[])
{// ① 创建用于通信的套接字文件描述符int cfd =socket(AF_INET,SOCK_DGRAM,0);if(cfd == -1){perror("socket error");return -1;}// ② 绑定IP地址和端口号// 2.1 填充地址信息结构体struct sockaddr_in sin;sin.sin_family =AF_INET;sin.sin_port =htons(SER_PORT);sin.sin_addr.s_addr =inet_addr(SER_IP);//2.2 绑定if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success\n");//③ 数据收发char wbuf[128] ="";//填充服务器的地址信息结构体 struct sockaddr_in sin;sin.sin_family =AF_INET;sin.sin_port =htons(SER_PORT);sin.sin_addr.s_addr =inet_addr(SER_IP);char rbuf[128] ="";while(1){//清空容器bzero(wbuf,sizeof(wbuf));bzero(rbuf,sizeof(rbuf));//从终端获取信息fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;//将消息发送给服务器sendto(cfd,rbuf,sizeof(rbuf),0,NULL,NULL);printf("接收到的服务器消息为:%s\n",rbuf);//④ 关闭套接字close(cfd);}return 0;
}