1、1. 第 7 层 应用层: 常见的协议有 : HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3 等第 6 层 表示层: 为不同的客户端提供数据和信息的语法转换内码,使系统能解读成正确的数据。同时,也能提供压缩解压、加密解密。第 5 层 会话层: 会话层用于为通信双方制定通信方式,并创建、注销会话(双方通信)第 4 层 传输层:用于控制数据流量,并且进行调试及错误处理,以确保通信顺利。而传送端的传输层会为分组加上序号,方便接收端把分组重组为有用的数据或文件。第 3 层 网络层: 网络层的作用是决定如何将发送方的数据传到接收方。该层通过考虑网络拥塞程度、服务质量、发送优先权、
2、每次路由的耗费来决定节点 X 到节点 Y 的最佳路径。我们熟知的路由器就工作在这一层,通过不断的接收与传送数据使得网络变得相互联通。第 2 层 数据链路层 : 首先数据链路层的功能在于管理第一层的比特数据,并且将正确的数据传送到没有传输错误的路线中。创建还有辨认数据开始以及退出的位置同时予以标记。另外,就是处理由数据受损、丢失甚至重复传输错误的问题,使后续的层级不会受到影响,所以它运行数据的调试、重传或修正,还有决定设备何时进行传输。 设备有:Bridge 桥接器 switch 交换器第 1 层 物理层 : 物理层定义了所有电子及物理设备的规范。其中特别定义了设备与物理媒介之间的关系,这包括了
3、针脚、电压、线缆规范、集线器、中继器、网卡、主机适配器(在 SAN 中使用的主机适配器)以及其他的设备的设计定义。因为物理层传送的是原始的比特数据流,即设计的目的是为了保证当发送时的信号为二进制“1”时,对方接收到的也是二进制“1”而不是二进制“0” 。因而就需要定义哪个设备有几个针脚,其中哪个针脚发送的多少电压代表二进制“1”或二进制“0 ”,还有例如一个 bit 需要持续几微秒,传输信号是否在双向上同时进行,最初的连接如何创建和最终如何终止等问题。2.TCP/IP 协议簇:应用层:telnet,ftp 传输层:TCP/UDP 网络层:ICMP,IGMP,IPv4,IPv6 网络接口层:AR
4、P,RARP,MPLS3, ARP:用于获得同一物理网络中的硬件主机地址。MPLS:多协议标签协议,是很有发展前景的下一代网络协议。IP:负责在主机和网络之间寻址和路由数据包。ICMP:用于发送报告有关数据包的传送错误的协议。IGMP:被 IP 主机用来向本地多路广播路由器报告主机组成员的协议。TCP:为应用程序提供可靠的通信连接。适合于一次传输大批数据的情况。并适用于要求得到响应的应用程序。UDP:提供了无连接通信,且不对传送包进行可靠的保证。适合于一次传输少量数据,Linux 线程的实现由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止
5、而得到释放。正如进程之间可以用 wait()系统调用来同步终止并释放资源一样,线程之间也有类似机制,那就是pthread_join()函数。在进行多线程编程时,常出现 undefined reference to pthread_create的错误,解决办法是:加上-lpthread 选项几个常用的数据结构4、定义:所谓三次握手,是指建立一个 TCP 连接时,需要客户端和服务器总共发送 3 个包。目的:三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.在 socket 编程中,客户端执行 connect()时,将触发三次握手。5
6、、第一次握手:客户端发送一个 TCP 的 SYN 标志位置 1 的包指明客户打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号字段里。第三次握手.客户端再次发送确认包(ACK) SYN 标志位为 0,ACK 标志位为 1.并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方.并且在数据段放写 ISN 的+16、SYN 攻击在三次握手过程中,服务器发送 SYN-ACK 之后,收到客户端的 ACK 之前的 TCP 连接称为半连接(half-open connect).此时服务器处于 Syn_RECV 状态.当收到 ACK 后,服务器转入 ESTABLISHED 状态.Syn
7、 攻击就是 攻击客户端 在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 syn 包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直 至超时,这些伪造的 SYN 包将长时间占用未连接队列,正常的 SYN 请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。Syn 攻击是一个典型的 DDOS 攻击。检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击.在 Linux 下可以如下命令检测是否被 Syn 攻击netstat -n -p TCP | grep SYN_
8、RECV7、TCP 四次挥手TCP 的连接的拆除需要发送四个包,因此称为四次挥手。客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close()操作即可产生挥手操作8、断开一个连接,为什么要四次挥手由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个 FIN 来终止这个方向的连接。收到一个 FIN 只意味着这一方向上没有数据流动,一个 TCP 连接在收到一个 FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。9、 (1)socket :该函数用于建立一个 socket 连接,可指定
9、 socket 类型等信息。在建立了 socket 连接之后,可对socketadd 或 sockaddr_in 进行初始化,以保存所建立的 socket 信息。(2)Bind :该函数是用于将本地 IP 地址绑定端口号的,若绑定其他地址则不能成功。(3)connect:该函数在 TCP 中是用于 bind 的之后的 client 端,用于与服务器端建立连接(4)Send 和 recv:这两个函数用于接收和发送数据,可以用在 TCP 中,也可以用在 UDP 中。当用在 UDP 时,可以在 connect 函数建立连接之后再用。(5)sendto 和 recvfrom:这两个函数的作用与 sen
10、d 和 recv 函数类型,也可以用在 TCP 和 UDP 中。当用在 TCP 时,后面的几个与地址有关参数不起作用,函数作用等同于 send 和 recv;当用在 UDP 时,可以用在之前没有使用 connect的情况时,这两个函数可以自动寻找制定地址并进行连接。10.socket 流程图11、int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);sockfd:标识一个套接口的描述字。level:选项定义的层次;支持 SOL_SOCKET、IPPROTO_TCP、IPPR
11、OTO_IP 和 IPPROTO_IPV6。optname:需设置的选项。optval: 指针,指向存放选项值的缓冲区。optlen:optval 缓冲区长度。Gethostname 函数原型Hostent 结构Hostent 各字段描述char *h_name 表示的是主机的规范名。例如 的规范名其实是 。 char *h_aliases 表示的是主机的别名。 就是 google 他自己的别名 int h_addrtype 表示的是主机 ip 地址的类型,到底是 ipv4(AF_INET),还是 ipv6(AF_INET6) int h_length 表示的是主机 ip 地址的长度 int
12、 *h_addr_list 表示的是主机的 ip 地址,注意,这个是以网络字节序存储的 一、 实验 2: gethostbyname 的使用int main(int argc,char *argv)if(argc !=2)printf(“Usage is %s hostnamen“,argv0);return -1;struct hostent *server = gethostbyname(argv1);/函数原型struct sockaddr_in addr;addr.sin_addr.s_addr = *(int *)(server-h_addr);printf(“h_name %sn“
13、,server-h_name);printf(“h_alias %sn“,server-h_aliases0);printf(“h_haddr 0x%xn“,*(int *)server-h_addr);printf(“h_haddr addr %sn“,inet_ntoa(addr.sin_addr);return 0;二、UDP 多线程实验Udp_server:int main(int argc, char *argv)int sockfd, len, opt = 1;struct sockaddr_in cliaddr;uint8_t bufferBUFFER_SIZE;int ret
14、= RET_OK;memset(buffer,0xff,sizeof(buffer);if(sockfd = socket(AF_INET, SOCK_DGRAM, 0) 0)printf(“Recv from %srn“, inet_ntoa(cliaddr.sin_addr);ret = sendto(sockfd, buffer, ret, 0, (struct sockaddr *)while(ret = 0);failed:close(sockfd);return 0;Udp_client:int main(int argc, char *argv)int sockfd, ret =
15、 RET_OK;struct sockaddr_in servaddr;struct hostent *server;struct in_addr ap;char bufferBUFFER_SIZE;memset(buffer, 0xff,sizeof(buffer);if (argc h_addr);if(sockfd = socket(AF_INET, SOCK_DGRAM, 0) h_addr;servaddr.sin_port = htons(uint16_t)ECHO_PORT);while(1)printf(“Enter the message : “);if(fgets(buff
16、er, sizeof(buffer) - 1, stdin) = NULL)break;if(ret = sendto(sockfd, buffer ,strlen(buffer), 0, (struct sockaddr *)strcpy(outPtr,ptr-fileName);/复制文件(6)完成 getFileNameFromMsg 函数后,请思考,如何验证你已经正确得到了要传输的文件名?回答:1.在 getFileNameFromMsg 函数最后把获得的文件输出到控制台,验证是否收到正确的文件名。2.使用抓包工具,检测程序接收到的包的数据是否有误。(7)请完成 send_file_a
17、ck 函数主体代码的编写,该函数用于发送确认消息,允许文件传输。void send_file_ack(int fd)struct MsgFileAck ack; /变量名字随意,别都一样是 ackack.msgType = MSG_FILE_ACK;ack.result = 1;/告诉客户机我们接受这个消息if(send(fd,bzero(if(connect(sockfd,(struct sockaddr *)exit(1);printf(“please input the file you want to open:n“);scanf(“%s“,file_name);printf(“buf
18、 is %sn“,file_name);fd=open(file_name,O_RDWR | O_CREAT, 0666);if(fd msgType = MSG_FILE_ACK)if(pMsg-result != 1)printf(“transfer failn“);return;printf(“press s to send filen“);getchar();while(readbytes = read(fd, buf,MAXDATASIZE) )if(sendbytes=send(sockfd, buf, readbytes,0)=-1)perror(“send“);exit(1);
19、totalbytes += sendbytes;printf(“sent %d bytes n“, totalbytes);close(sockfd):1、请写出 gethostbyname 函数的原型,并解释各参数的作用?该函数能完成什么功能?函数原型为 struct hostent *gethostbyname(const char *name);返回 hostent 结构体类型指针:struct hostentchar *h_name;char *h_aliases;int h_addrtype;int h_length;char *h_addr_list;其中,hostent-h_na
20、me 表示的是主机的规范名。例如 的规范名其实是 。hostent-h_aliases 表示的是主机的别名。 就是 google 他自己的别名hostent-h_addrtype 表示的是主机 ip 地址的类型,到底是 ipv4(AF_INET),还是 ipv6(AF_INET6)hostent-h_length 表示的是主机 ip 地址的长度hostent-h_addr_list 表示的是主机的 ip 地址,这个是以网络字节序存储的。该函数的功能是用域名或主机名获取 IP 地址。2、在 C 语言里,如何强制 2 字节对齐?比如在一个工程里,有 1 个.h 文件,2 个.c 文件,所有的数据
21、结构类型都定义在.h 文件里,请问,强制 2 字节对齐的语句应该回在哪个文件里面,加的时候有什么要求?#pragma pack 是指定数据在内存中的对齐方式。在 C 语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如 int、long、float 等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。强制字节对齐的语句应该回到.h 文件里面,加的时候要指定对齐值,如字节对齐:pragma pack(
22、2)。3、简述 tcp 与 udp 的异同点tcp 面向连接,提供可靠的数据传输,但传输速度比 udp 慢,应用在需要传输大量的数据的场合中;udp 面向非连接,不一定提供可靠的数据传输,传输速度快,适用于传输少量数据的场合中4、 假设你写了一个基于网络的客户端与服务器,它们之间通过 TCP/IP 进行通讯,但不知什么原因,服务器一直都收不到客户端的消息,客户端也收不到来自服务器的消息,请问,你会采用什么方法来解决这个问题?试描述你的解决办法及思路答:在服务器和客户端中设置断点调试,或者用 gdb 调试,测试哪里代码出现问题。5.请问,服务器如何才能检测到客户端的退出?站在程序的角度,应该如何
23、写代码,通过什么来判断?答:通过心跳包来确保客户端是否正常连接,比如定时发心跳包给客户端,然后接收回应包,如果没有收到该回应包则可以认为客户端已经断开连接;可以查看 read 函数的返回值来进行判断。6、 例如,一个客户端想发送一个文件请求消息,消息里面需要带需要发送的文件名,假设,你现在已经有一个QString path 里面包含了带文件名的完整路径(“/home/test/1m.rar”),此时你需要把 1m.rar 文件名提取出来,如何实现,代码如下:scanf(“%s“,path);printf(“buf is %sn“,path);fd=open(path,O_RDWR | O_CR
24、EAT, 0666);if(fd 0)perror(“open“);exit(1);7、有人说,TCP 是安全的,你同意吗?为什么?答:不同意。TCP 使用三次握手机制来建立一条连接,握手的第一个报文为 SYN 包;第二个报文为 SYN/ACK 包,表明它应答第一个 SYN 包同时继续握手的过程;第三个报文仅仅是一个应答,表示为 ACK 包。若 A 放为连接方,B 为响应方,其间可能的威胁有:1. 攻击者监听 B 方发出的 SYN/ACK 报文。2. 攻击者向 B 方发送 RST 包,接着发送 SYN 包,假冒 A 方发起新的连接。3. B 方响应新连接,并发送连接响应报文 SYN/ACK。4
25、. 攻击者再假冒 A 方对 B 方发送 ACK 包。这样攻击者便达到了破坏连接的作用,若攻击者再趁机插入有害数据包,则后果更严重。TCP 协议把通过连接而传输的数据看成是字节流,用一个 32 位整数对传送的字节编号。初始序列号(ISN)在 TCP 握手时产生,产生机制与协议实现有关。攻击者只要向目标主机发送一个连接请求,即可获得上次连接的 ISN,再通过多次测量来回传输路径,得到进攻主机到目标主机之间数据包传送的来回时间 RTT。已知上次连接的 ISN 和 RTT,很容易就能预测下一次连接的 ISN。若攻击者假冒信任主机向目标主机发出 TCP 连接,并预测到目标主机的 TCP 序列号,攻击者就
26、能伪造有害数据包,使之被目标主机接受。8、 在 TCP 服务器端,有客户端登录,TCP 服务器是如何检测到有新的客户连接的?服务器如何才知道客户端的 IP 及端口号?在服务器端获取的 IP 及端口号一定是客户端本机发出时的 IP 及端口号吗?为什么?答:服务器中的 accept()函数等待并接受客户的连接。accept 默认会阻塞进程,直到有一个客户连接建立后返回,它返回的是一个新可用的连接套接字 sockfd。这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个一个端口号,而此时这个端口号正与这个套接字关联,这样服务器就知道客户端的 IP 地址和端口号。9、 在编写服务器的时候
27、,一般我们会进行端口绑定,请问使用的是什么 api?如果服务器不绑定端口,会有什么样的影响?答:用 bind 函数进行端口绑定。如果服务器不绑定端口,连接的端口号会随机一个。10、 假设两台机器,一台机器 A 在中山,局域网 ip 地址为 192.168.0.11。另一台机器 B 在北京,局域网 IP 为192.168.1.12,两台机器均可访问互联网。如果要让这两台机器进行文件传输,需要怎么做? 答:先让这两台机器 A,B 分别登录 http 服务器,这样服务器分别登记了 A 和 B 的 NAT 后的 IP 地址与端口号;接着假设 A 想发文件给 B,A 就会向服务器获取 B 的 IP 地址
28、,并发送 UDP 信息给 B。第一次会请求失败,此时 A 报告服务器要求服务器帮忙对 B 进行通知。服务器收到此消息后,将 A 的 IP 地址发送给 B,要求 B 连接。B 收到服务器的信息后发送请求到 A,由于此时 A 的 NAT 已经存在 B 的 session,所以此时 A 与 B 建立链接成功。所以 A 发送文件到 B成功,不用经过服务器中转,这就是 udp 打洞原理。11、 请问网卡、集线器、路由器、交换机分别工作在 TCP/IP 网络的哪一层?答:网卡和交换机工作在 TCP/IP 网络的数据链路层;集线器工作在 TCP/IP 网络的物理层;路由器工作在 TCP/IP 网络的网络层。