模拟面试
1、什么是IP地址?
IP地址是计算机在网络中通信的唯一标识,由两部分组成:网络号和主机号,网络号是确定计算机所属网络,主机号是确定计算机在网络中的一个编号。ip地址分为两类:ipv4和ipv6,ipv4的取值范围:[0, 3^32-1],IPv6不兼容IPv4。
2、ip的划分
ip地址由于数量庞大划分为五类:A类地址第一个字节的取值范围:0~127;B类地址的一个字节的取值范围:128~191;c类地址第一个字节的取值范围:192~223;D类地址第一个字节的取值范围是:224~239;E类地址第一个字节的取值范围是:240~255,E类地址没有主机位,保留或给实验室使用。
3、IP地址中200.0.0.1这个ip地址属于哪一类网络?
属于c类网络,c类网络范围:192.0.0.0~223.255.255.255
4、什么是端口号?端口号的作用?
端口号是为了区分同一主机上的多个进程,使用端口号来进行处理,端口号是一个2字节的无符号整数存储。
5、谈谈你对字节序的理解?
不同主机的字节序更具其需求可能是不同的,分为大端存储与小端存储,大端存储:低地址位存储数据的高位的存储方式;小端存储:低地址位存储数据的低位的存储方式,字节序的不同在多平台数据交换时尤为重要,因为不同机器之间的数据交换需要考虑到端序的转换,以确保数据的正确解释和使用,在进行多字节整数网络传输时,需要使用字节序的转换,网络传输字节序规定是为大端存储。
6、7层网络体系结构?
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
7、在tcp/ip协议族体系结构中,http、tftp、ip、udp、arp协议分别在哪一层
http在应用层、tftp在应用层、ip在网络层、udp在传输层、arp在网络层
8、tcp和udp的区别
tcp稳定提供面向连接的,可靠的数据传输服务,传输过程中,数据无误、数据无丢失、数据无失序、数据无重复,数据传输效率低,耗费资源多;udp面向无连接的,不保证数据可靠的,尽最大努力传输的协议,数据传输过程中,可能出现数据丢失、重复、失序现象。
9、tcp通信过程中服务器端实现流程
1、创建连接的套接字描述符
2、bind绑定IP地址和端口号
3、listen设置成被动监听状态
4、accept如果有客户机发来连接请求则创建一个用于通信的套接字描述符
5、数据读写 可用:send、recv
6、close关闭
10、udp通信过程中服务器端实现流程
1、创建连接的套接字描述符
2、bind绑定IP地址和端口号
3、数据接收 可用:sendto、recvfrom
4、close关闭
TCP服务器端
#include<header.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.146"
int main(int argc, const char *argv[])
{
//1\为通信创建一个端点
int sfd = socket(AF_INET,SOCK_STREAM,0);
if (sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success sfd =%d\n",sfd);// 0 1 2已经打开了 所以最小原则是3
//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 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("[%s:%d]发来连接请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
//5与客户端进行互相通信
char rbuf[128]="";
while(1)
{
//清空容器
bzero(rbuf,sizeof(rbuf));
//从套接字中读取数据
int res = recv(newfd,rbuf,sizeof(rbuf),0);
if(res == 0)
{
printf("客户端已经下线\n");
break;
}
//将读取的消息展示出来
printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf);
//将收到消息处理,回复客户端
strcat(rbuf,"^_^!");
//将消息发送给客户端
send(newfd,rbuf,strlen(rbuf),0);
printf("发送成功\n");
}
return 0;
}
TCP客户端
#include<header.h>
#define SER_PORT 8888
#define CLI_PORT 6666
#define SER_IP "192.168.125.146"
#define CLI_IP "192.168.125.146"
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("cfd = %d\n",cfd);
//2、绑定IP地址和端口号
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("连接成功\n");
//3、连接服务器
//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;
//把数据发给服务器
send(cfd,wbuf,strlen(wbuf),0);
printf("发送成功\n");
//接收服务器回信
bzero(rbuf,sizeof(rbuf));
recv(cfd,rbuf,sizeof(rbuf),0);
printf("服务器发来的消息:%s\n",rbuf);
}
//5、关闭套接字
close(cfd);
return 0;
UDP服务器端
#include<header.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.146"
int main(int argc, const char *argv[])
{
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success sfd = %d\n",sfd);
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)) ==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//数据收发
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);
strcat(rbuf,"*.*");
if(sendto(sfd,rbuf,strlen(rbuf),0,(struct sockaddr*)&cin,sizeof(cin))==-1)
{
perror("write error");
return -1;
}
printf("发送成功\n");
}
close(sfd);
return 0;
}
UDP客户端
#include<header.h>
#define CLI_IP "192.168.125.146"
#define SER_IP "192.168.125.146"
#define SER_PORT 8888
#define CLI_PORT 6666
int main(int argc, const char *argv[])
{
//1、创建用于通信的套接字文件描述符
int cfd = socket(AF_INET,SOCK_DGRAM,0);
if(cfd == -1)
{
perror("socket error");
return -1;
}
printf("cfd = %d\n",cfd);//3
//2、数据收发
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(rbuf,sizeof(rbuf));
bzero(wbuf,sizeof(wbuf));
//从终端获取信息
fgets(wbuf,sizeof(wbuf),stdin);
wbuf[strlen(wbuf)-1]=0;
//把信息发送给服务器
sendto(cfd,wbuf,strlen(wbuf),0,(struct sockaddr*)&sin,sizeof(sin));
printf("发送成功\n");
//接收服务器发来的消息
recvfrom(cfd,rbuf,sizeof(rbuf),0,NULL,NULL);
printf("收到服务器消息:%s\n",rbuf);
}
//3、关闭套接字
close(cfd);
return 0;
}