Socket通信流程-基于Java多线程实现Socket异步通信

本文详细介绍了Java中的Socket和ServerSocket类如何用于建立通信连接,阐述了服务原语如BIND、LISTEN、ACCEPT、CONNECT、SEND、RECEIVE和CLOSE在服务器端和客户端的应用。通过示例代码展示了如何创建并发线程进行数据的发送和接收,以及如何优雅地关闭连接。
摘要由CSDN通过智能技术生成

服务原语Primitive

实现原理

对应Java命令

ServerSocket---用于建立通信连接的对象

Socket---用于通信的对象

服务原语

Server端

Client端

SOCKET创建一端的socket,也是一个通信的线程,允许有多个

ServerSocket server = new ServerSocket(PORT);

默认绑定本地IP,端口号PORT需要在初始化中定义

Socket socket = new Socket();

默认绑定本地IP

BIND将socket与本地地址绑定

LISTEN监听连接的请求

Socket socket = server.accept();

此时线程阻塞,监听来自Client端的连接,当Client端发起connect命令

ACCEPT被动的接收连接请求

CONNECT主动发起请求

socket.connect(IP:PORT);

SEND

socket.getOutputStream();

RECEIVE

socket.getInputStream();

CLOSE主动断开请求

socket.close();

Server端代码

public class Server extends  Port{
    public static void main(String[] args) {
        try {
            //初始化ServerSocket
            ServerSocket server = new ServerSocket(2000);
            //阻塞等待客户端连接
            //一旦建立连接,初始化Socket
            Socket client=server.accept();

            try {
                new SendThread(client).start();
                new ReplyThread(client).start();
            } catch (Exception e) {
                System.out.println("异常关闭");
            } finally {
                //SendThread和ReplyThread之一的线程释放了锁,才能关闭Socket
                synchronized (lock) {
                    lock.wait();
                }
                client.close();
                server.close();
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Client端代码

public class Client extends Port{
    public static void main(String[] args) {
        try {
            //初始化Socket
            Socket client = new Socket();
            client.setSoTimeout(300000);
            //初始化连接服务器ServerSocket
            client.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000));

            try {
                new SendThread(client).start();
                new ReplyThread(client).start();
            } catch (Exception e) {
                System.out.println("异常关闭");
            } finally {
                //SendThread和ReplyThread之一的线程释放了锁,才能关闭Socket
                synchronized (lock) {
                    lock.wait();
                }
                client.close();
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Server和Client继承的父类

public class Port {

    public static final Object lock = new Object();

}

发送线程代码

@AllArgsConstructor
public class SendThread extends Thread {

    private Socket socket;

    @SneakyThrows
    @Override
    public void run() {
        BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
        PrintStream send=new PrintStream(socket.getOutputStream());

        do {
            //键盘(当前)--->程序(当前)
            String sendMsg = input.readLine();
            //程序(当前)--->程序(对面)
            send.println(sendMsg);
            if("Esc".equals(sendMsg)) break;
        } while (true);
        synchronized (Port.lock) {
            Port.lock.notify();
        }
    }
}

接收线程代码

@AllArgsConstructor
public class ReplyThread extends Thread {

    private Socket socket;

    @SneakyThrows
    @Override
    public void run() {
        BufferedReader reply=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream output = System.out;

        do {
            //程序(对面)--->程序(当前)
            String replyMsg = reply.readLine();
            //程序(当前)--->键盘(当前)
            output.println(replyMsg);
            if("Esc".equals(replyMsg)) break;
        } while(true);
        synchronized (Port.lock) {
            Port.lock.notify();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值