Java演示TCP 3次握手与 4次分手

news/2024/5/17 18:50:59 标签: java, tcp, socket

啥都不说,先上代码。
服务端:

java">package com.ghs.test;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServerSocket {
    private static ServerSocket serverSocket;
    private static Socket socket;

    public static void startServerSocket(int bindPort) {
        try {
            serverSocket = new ServerSocket(bindPort);
            while(true){
                socket = serverSocket.accept();
                System.out.println("连接的客户端地址和端口为:" + socket.getRemoteSocketAddress());
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        startServerSocket(6000);
    }
}

客户端:

java">package com.ghs.test;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClientSocket {

    private static Socket socket;

    javadoc">/**
     * 是否主动发起关闭
     */
    private static boolean isLaunchClose=true;

    javadoc">/**
     * 建立socket连接
     * 
     *javadoctag"> @param bindIp
     *javadoctag"> @param bindPort
     */
    public static void connectServerSocket(String bindIp, int bindPort) {
        try {
            socket = new Socket(bindIp, bindPort);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    javadoc">/**
     * 关闭socket连接
     */
    public static void closeSocket(){
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        int bindPort = 6000;
        String bindIp = "192.168.1.36";
        connectServerSocket(bindIp, bindPort);
        if(!isLaunchClose){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        closeSocket();
    }
}

先启动服务端,然后启动客户端,通过wireshark软件进行抓包。结果如下这里写图片描述

注:实际操作过程中,抓取的包可能是下面这样,不过红色部分可以不加
考虑
这里写图片描述
附:如果你本地无法抓包,请参考
https://yq.aliyun.com/ziliao/140472

下面,简单的介绍一下,TCP的3次握手和4次分手。
先上一个经典图形。
这里写图片描述

3次握手
当服务的启动之后,处于LISTEN状态。
当客户端执行下面的代码后,就开始了3次握手

socket = new Socket(bindIp, bindPort)

客户端首先发送一个SYN报文,服务端返回一个SYN+ACK报文,客户端再回一个ACK报文

4次分手
当客户端执行下面的代码后

socket.close();

客户端会发送一个FIN+ACK报文,服务端会响应一个ACK报文。
此时,客户端处于FIN_WAIT_2状态,服务端处于CLOSE_WAIT状态。

当服务端执行下面的代码后

socket.close();

服务端会发送一个FIN报文,进入LAST_ACK状态
客户端返回一个ACK报文,进入TIME_WAIT状态

至于TCP为什么要经过3个握手4次分手,可以参考下面这篇博文。
http://www.jellythink.com/archives/705


http://www.niftyadmin.cn/n/1530583.html

相关文章

netstat查看当前网络下TCP的各种状态

命令如下: netstat -nat|awk {print $6}|sort|uniq -c|sort -rn 附: 有关sort命令,可参考 http://www.cnblogs.com/dong008259/archive/2011/12/08/2281214.html有关uniq命令,可参考 http://blog.csdn.net/jesseen/article/d…

Linux用户及权限管理

一、用户管理 1、创建用户 //创建monitor用户,用户id为501,所属组为monitor,附加群组为admin,起始目录为/monitor useradd -u 501 -g monitor -G admin -d /monitor monitor -u:直接给出userID -g:指定用户所属的群组 -G 指定…

org.springframework.jdbc.UncategorizedSQLException

当出现UncategorizedSQLException时,很可能是下面几种情况。 1、本来是查询一条记录,但是返回了多条

aop:aspect与aop:advisor的区别

在开发过程中&#xff0c;不少有Spring Aop的使用&#xff0c;在面向切面编程时&#xff0c;我们会使用< aop:aspect>&#xff1b;在进行事务管理时&#xff0c;我们会使用< aop:advisor>。那么&#xff0c;对于< aop:aspect>与< aop:advisor>的区别&a…

nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type

在使用cglib进行动态代理时&#xff0c;很可能会出现下面的异常&#xff1a; NoClassDefFoundError: org/objectweb/asm/Type 当这种异常出现时&#xff0c;可能从下面几个方法查找问题。 1、asm包有没有导入 由于cglib动态代理需要使用asm反射包&#xff0c;所以&#xff…

Sping-AOP:cglib动态代理与JDK动态代理的区别

默认状态下&#xff0c;Spring-AOP默认使用JDK动态代理&#xff0c;当需要代理的对象没有实现任何接口时&#xff0c;才使用cglib动态代理。 下面&#xff0c;将向大家介绍JDK动态代理和Cglib动态代理的使用、两者的区别已经注意事项。 一、JDK动态代理 由于JDK动态代理是基…

Java获取类、方法、属性上的注解

一、获取类上的注解 Java获取类上的注解有下面3个方法&#xff1a; Class.getAnnotations() 获取所有的注解&#xff0c;包括自己声明的以及继承的Class.getAnnotation(Class< A > annotationClass) 获取指定的注解&#xff0c;该注解可以是自己声明的&#xff0c;也可…

Linux crontab 定时执行任务

一、crontab使用方式 crontab file [-u user]-用指定的文件替代目前的定时任务。 crontab -u user]-用标准输入替代目前的定时任务. crontab -l [user]-列出用户目前的定时任务. crontab -e [user]-编辑用户目前的定时任务. crontab -d [user]-删除用户目前的定时任务. c…