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

170 阅读6分钟

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

====讲一讲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();

}

}

}

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