1.什么是IP地址?
答:IP地址是计算机在网络中的唯一标识,它有两部分组成,分别是区分子网的网络号和区分主机的主机号,网络号确定计算机所从属的网络,主机号标识设备在该网络下的一个编号
2.IP的划分?
答:IP地址共分为5类,分别是A、B、C、D、E
其中A类网络可分配的地址范围是1.0.0.1到127.255.255.254
B类网络可分配的地址范围是128.0.0.1到191.255.255.254
C类网络可分配的地址范围是192.0.0.1到223.255.255.254
D类网络为组播地址,范围是224.0.0.0到239.255.255.255
E类网络为保留地址,范围是240.0.0.0到255.255.255.255
3.IP地址中200.0.0.1这个IP地址属于哪一类网路?
答:属于C类网络,可分配地址范围为192.0.0.1-223.255.255.254
4.什么是端口号?端口号的作用?
答:端口号是一个2字节的无符号整数,取值范围0到65535
0到1023号端口为系统定义的端口号,不可更改
1024到49151为我们平常定义使用的端口号
49152到65535为客户端运行时动态分配的端口
5.谈谈你对字节序的理解?
答:字节序是指多字节整数在计算机内存中存储或者网络传输时各字节的存储顺序。计算机中常见的存储方式有两种,分别为大端存储和小端存储。大端存储是地址低位存储数据高位,小端存储是地址低位存储数据低位。而多字节整数在网络中传输的存储方式称为网络字节序,规定网络字节序为大端存储。
6.7层网络体系结构?
答:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
7.在TCP/IP协议族体系结构中,http、tftp、ip、udp、arp协议分别在哪一层?
答:http、tftp位于应用层;udp位于传输层;ip位于网际层;arp位于网络接口层
8.TCP和UDP通信的区别?
答:1).TCP提供面向连接的,有序的,可靠的,面向字节流的数据传输服务,而UDP提供面向无连接的,不保证数据可靠的,尽最大努力交付的,面向报文的数据传输服务;
2).TCP仅支持点对点的单播通信,而UDP不仅支持点对点的通信,还支持一对多,多对多,多对一的组播和广播通信
3).TCP首部最小20字节,最大60字节,而UDP首部开销小,仅8字节
4).TCP适用于要求可靠传输的应用,例如文件传输,UDP适用于实时应用,例如网络电话,视频会议,直播等
9.TCP通信过程中,服务器端实现流程?
答:socket:为网络通信提供一个端点,并返回该端点的文件描述符,文件描述符使用原则为最小未分配原则
bind:为给定的套接字文件描述符绑定IP地址和端口号
listen:将给定的套接字设置成被动监听状态
accept:阻塞等待客户端的连接请求,如果有客户端发来连接请求,则会创建一个新的用于通信的套接字文件描述符
send/recv:数据收发
close:关闭文件
10.UDP通信中,服务器端实现?
答:socket:为网络通信提供一个端点,并返回该端点的文件描述符,文件描述符使用原则为最小未分配原则
bind:为给定的套接字文件描述符绑定IP地址和端口号
sendto/recvfrom:数据收发
close:关闭文件
tcps.c
#include <myhead.h>
#define IP "192.168.88.128"
#define PORT 8888
int main(int argc, const char *argv[])
{
//创建一个套接字端点并返回该端点的文件描述符
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1){
perror("socket");
return -1;
}
//为给定的套接字文件描述符绑定IP地址和端口号
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
socklen_t sinlen = sizeof(sin);
if(bind(sfd, (struct sockaddr *)&sin, sinlen) == -1){
perror("bind");
return -1;
}
//将给定的套接字设置成被动监听状态
if(listen(sfd, 128) == -1){
perror("listen");
return -1;
}
//阻塞等待客户端的连接请求,若有,则创建一个新的用于通信的套接字文件描述符
struct sockaddr_in cin;
socklen_t cinlen;
int newfd = accept(sfd, (struct sockaddr *)&cin, &cinlen);
if(newfd == -1){
perror("accept");
return -1;
}
printf("accept success\n");
//数据收发
char rbuf[128] = {0};
while(1){
bzero(rbuf, sizeof(rbuf));
int size = recv(newfd, rbuf, sizeof(rbuf), 0);
if(size == 0){
printf("client is offline\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);
}
//关闭文件
close(newfd);
close(sfd);
return 0;
}
tcpc.c
#include <myhead.h>
#define S_IP "192.168.88.128"
#define S_PORT 8888
#define C_IP "192.168.88.128"
#define C_PORT 6666
int main(int argc, const char *argv[])
{
//创建套接字端点,并返回该端点的文件描述符
int cfd = socket(AF_INET, SOCK_STREAM, 0);
if(cfd == -1){
perror("socket");
return -1;
}
//为给定的套接字文件描述符绑定IP地址和端口号
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(C_PORT);
cin.sin_addr.s_addr = inet_addr(C_IP);
socklen_t cinlen = sizeof(cin);
if(bind(cfd, (struct sockaddr *)&cin, cinlen) == -1){
perror("bind");
return -1;
}
//请求连接服务端
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(S_PORT);
sin.sin_addr.s_addr = inet_addr(S_IP);
socklen_t sinlen = sizeof(sin);
if(connect(cfd, (struct sockaddr *)&sin, sinlen) == -1){
perror("connect");
return -1;
}
printf("connect success\n");
//数据收发
char wbuf[128] = {0};
char rbuf[128] = {0};
while(1){
bzero(wbuf, sizeof(wbuf));
fgets(wbuf, sizeof(wbuf), stdin);
int len = strlen(wbuf);
if(wbuf[len-1] == '\n'){
wbuf[len-1] = 0;
}
send(cfd, wbuf, len, 0);
bzero(rbuf, sizeof(rbuf));
recv(cfd, rbuf, sizeof(rbuf), 0);
printf("[%s:%d]:%s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), rbuf);
}
//关闭文件
close(cfd);
return 0;
}
udps.c
#include <myhead.h>
#define IP "192.168.88.128"
#define PORT 8888
int main(int argc, const char *argv[])
{
//创建套接字端点,并返回该端点的文件描述符
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd == -1){
perror("socket");
return -1;
}
//为给定的套接字文件描述符绑定IP地址和端口号
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
socklen_t sinlen = sizeof(sin);
if(bind(sfd, (struct sockaddr *)&sin, sinlen) == -1){
perror("bind");
return -1;
}
//数据收发
char rbuf[128] = {0};
struct sockaddr_in cin;
socklen_t cinlen;
while(1){
bzero(rbuf, sizeof(rbuf));
recvfrom(sfd, rbuf, sizeof(rbuf), 0, (struct sockaddr *)&cin, &cinlen);
printf("[%s:%d]:%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);
strcat(rbuf, "*_*");
sendto(sfd, rbuf, strlen(rbuf), 0, (struct sockaddr *)&cin, cinlen);
}
//关闭文件
close(sfd);
return 0;
}
udpc.c
#include <myhead.h>
#define S_IP "192.168.88.128"
#define S_PORT 8888
#define C_IP "192.168.88.128"
#define C_PORT 7777
int main(int argc, const char *argv[])
{
//创建套接字端点,并返回该端点的文件描述符
int cfd = socket(AF_INET, SOCK_DGRAM, 0);
if(cfd == -1){
perror("socket");
return -1;
}
//为给定的套接字文件描述符绑定IP地址和端口号
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(C_PORT);
cin.sin_addr.s_addr = inet_addr(C_IP);
socklen_t cinlen = sizeof(cin);
if(bind(cfd, (struct sockaddr *)&cin, cinlen) == -1){
perror("bind");
return -1;
}
//数据收发
char wbuf[128] = {0};
char rbuf[128] = {0};
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(S_PORT);
sin.sin_addr.s_addr = inet_addr(S_IP);
socklen_t sinlen = sizeof(sin);
while(1){
bzero(wbuf, sizeof(wbuf));
fgets(wbuf, sizeof(wbuf), stdin);
int len = strlen(wbuf);
if(wbuf[len-1] == '\n'){
wbuf[len-1] = 0;
}
sendto(cfd, wbuf, len, 0, (struct sockaddr *)&sin, sinlen);
bzero(rbuf, sizeof(rbuf));
recvfrom(cfd, rbuf, sizeof(rbuf), 0, (struct sockaddr *)&sin, &sinlen);
printf("[%s:%d]:%s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), rbuf);
}
//关闭文件
close(cfd);
return 0;
}