在第一次握手时,由《TCP/IP详解》卷二中对tcp计时器的描述中,我们可知连接的建立是需要进行判断,如果客户端发送了SYN连接请求,服务端没有在有限时间内进行恢复,就会取消本次连接。
我们使用 setSoTimeout() 来判断超时时间,当超过了我们的计时时间,会抛出一个RuntimeException异常,我们需要使用 try-catch来捕获这个异常,并且输出提示
//调用对象发送数据
datagramSocket.send(datagramPacket);
datagramSocket.setSoTimeout(75000);
System.out.println("====================");
System.out.println("接收数据中:...");
/**
* 在第二次握手中,客户端主要会检查两个方面的内容:
* 检查ACK标志位:客户端需要确认服务端发送的确认信息(SYN-ACK)中的ACK标志位是否已设置。ACK标志位表示服务端确认收到了客户端的握手请求。
* 检查确认号(ACK):客户端需要检查服务端发送的确认信息中的确认号(ACK)是否正确。确认号应该是服务端发送的初始序列号加1,用于告知服务端它已经正确接收到服务端的数据。
*/
//创建数据包,用于接收数据
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket2 = new DatagramPacket(bytes, bytes.length);
datagramSocket.receive(datagramPacket2);
//停止计时
datagramSocket.setSoTimeout(0);
if (
Integer.parseInt(strArr3[0]) != 1
|| Integer.parseInt(strArr3[1]) != Integer.parseInt(ACK2)
|| (Integer.parseInt(strArr3[2]) - 1) != Integer.parseInt(Seq2)
){
throw new WrongConnectionException("非本次连接");
}
注意:该方法不是完全合乎逻辑的,因为抛出异常后程序将会停止,而且接收到数据后才进行的判断。正常情况下应该在接收前进行判断是否为本次连接的内容,如若不是本次连接数据,应该忽略本次连接,继续等待数据。
创建异常类:
package TCP_handShake;
public class WrongConnectionException extends Exception{
public WrongConnectionException(String Msg) {
super(Msg);
}
}
异常捕获在上一个代码段。
catch (WrongConnectionException e) {
System.out.println("异常提醒:" + e.getMessage());
}