锁屏面试题百日百刷-面试必问四次挥手

锁屏面试题百日百刷,每个工作日坚持更新面试题。锁屏面试题app、小程序现已上线,官网地址:https://www.demosoftware.cc/#/introductionPage。已收录了每日更新的面试题的所有内容,还包含特色的解锁屏幕复习面试题、每日编程题目邮件推送等功能。让你在面试中先人一步,吊打面试官!接下来的是今日的面试题:

 

====讲一讲TCP中的四次挥手?

 

 

 

1). 第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;

 

2). 第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。

 

3). 第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;

 

4). 第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。

 

 

 

====TCP四次挥手中为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?

 

因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。

 

 

 

====TCP四次挥手中如果第二次挥手时服务器的ACK没有送达客户端,会怎样?

 

客户端没有收到ACK确认,会重新发送FIN请求。

 

 

 

====客户端TIME_WAIT状态的意义是什么?

 

第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。 MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

 

 

 

====什么是Socket?

 

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个

 

Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

 

但是,Socket所支持的协议种类也不光TCP/IP、UDP,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

 

socket连接就是所谓的长连接,客户端和服务器需要互相连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉的,但是有时候网络波动还是有可能的

 

Socket偏向于底层。一般很少直接使用Socket来编程,框架底层使用Socket比较多。

 

 

 

====Socket通讯的过程?

 

1)基于TCP:服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

 

2)基于UDP:UDP 协议是用户数据报协议的简称,也用于网络数据的传输。虽然 UDP 协议是一种不太可靠的协议,但有时在需要较快地接收数据并且可以忍受较小错误的情况下,UDP 就会表现出更大的优势。我客户端只需要发送,服务端能不能接收的到我不管

 

 

 

====java中基于TCP协议的socket代码?

 

1)服务端

 

package com.test.io;

 

import java.io.IOException;

 

import java.io.InputStream;

 

import java.io.OutputStream;import java.net.ServerSocket;

 

import java.net.Socket;

 

//TCP协议Socket使用BIO进行通行:服务端

 

public class BIOServer {

 

// 在main线程中执行下面这些代码

 

public static void main(String[] args) {

 

//1单线程服务

 

ServerSocket server = null;

 

Socket socket = null;

 

InputStream in = null;

 

OutputStream out = null;

 

try {

 

server = new ServerSocket(8000);

 

System.out.println("服务端启动成功,监听端口为8000,等待客户端连接...");

 

while (true){

 

socket = server.accept(); //等待客户端连接

 

System.out.println("客户连接成功,客户信息为:" +

 

socket.getRemoteSocketAddress());

 

in = socket.getInputStream();

 

byte[] buffer = new byte[1024];

 

int len = 0;

 

//读取客户端的数据

 

while ((len = in.read(buffer)) > 0) {

 

System.out.println(new String(buffer, 0, len));

 

}

 

//向客户端写数据

 

out = socket.getOutputStream();

 

out.write("hello!".getBytes());

 

}

 

} catch (IOException e) {

 

e.printStackTrace();

 

}

 

}

 

}

 

2)客户端

 

package com.test.io;

 

import java.io.IOException;

 

import java.io.OutputStream;

 

import java.net.Socket;

 

import java.util.Scanner;

 

//TCP协议Socket:客户端

 

public class Client01 {

 

public static void main(String[] args) throws IOException {

 

//创建套接字对象socket并封装ip与port

 

Socket socket = new Socket("127.0.0.1", 8000);

 

//根据创建的socket对象获得一个输出流

 

OutputStream outputStream = socket.getOutputStream();

 

//控制台输入以IO的形式发送到服务器

 

System.out.println("TCP连接成功 \n请输入:");

 

while(true){

 

byte[] car = new Scanner(System.in).nextLine().getBytes();

 

outputStream.write(car);

 

System.out.println("TCP协议的Socket发送成功");

 

//刷新缓冲区

 

outputStream.flush();

 

}

 

}

 

}

 

 

 

====java中基于UDP协议的socket代码?

 

1)服务端

 

//UDP协议Socket:服务端

 

public class Server1 {

 

public static void main(String[] args) {

 

try {

 

//DatagramSocket代表声明一个UDP协议的Socket

 

DatagramSocket socket = new DatagramSocket(8888);

 

//byte数组用于数据存储。

 

byte[] car = new byte[1024];

 

//DatagramPacket 类用来表示数据报包DatagramPacket

 

DatagramPacket packet = new DatagramPacket(car, car.length);

 

//创建DatagramSockett的receive()方法来进行数据的接收,等待接收一个socket

 

求后才执行后续操作;

 

System.out.println("等待UDP协议传输数据");

 

socket.receive(packet);

 

//packet.getLength返回将要发送或者接收的数据的长度。

 

int length = packet.getLength();

 

System.out.println("啥东西来了:" + new String(car, 0, length));

 

socket.close();

 

System.out.println("UDP协议Socket接受成功");

 

} catch (IOException e) {

 

e.printStackTrace();

 

}

 

}

 

}

 

2)客户端

 

//UDP协议Socket:客户端

 

public class Client1 {

 

public static void main(String[] args) {

 

try {

 

//DatagramSocket代表声明一个UDP协议的Socket

 

DatagramSocket socket = new DatagramSocket(2468);

 

//字符串存储人Byte数组

 

byte[] car = "UDP协议的Socket请求,有可能失败哟".getBytes();

 

//InetSocketAddress类主要作用是封装端口

 

InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8888);

 

//DatagramPacket 类用来表示数据报包DatagramPacket

 

DatagramPacket packet = new DatagramPacket(car, car.length,

 

address);

 

//send() 方法发送数据包。

 

socket.send(packet);

 

System.out.println("UDP协议的Socket发送成功");

 

socket.close();

 

} catch (Exception e) {

 

e.printStackTrace();

 

}

 

}

 

}

 

 

 

 

 

 

更多面试题或学习资源可查看我主页或评论获取

 

posted @ 2021-07-16 00:20  demo锁屏面试题  阅读(63)  评论(0)    收藏  举报