基于BIO的实时Socket读写操作

文章目录

  1. 前言
  2. Socket类
    2.1 Socket的通信过程
    2.2 控制Socket连接
    2.3 设置Socket的选项
  3. ServerSocket类
    3.1 构造ServerSocket
    3.2 ServerSocket的常用方法
    3.3 设置ServerSocket选项
  4. 基于TCP的BIO通信
    4.1 实现功能
    4.2 程序源代码
    4.3 程序效果截图

1. 前言

基于传输层协议TCP的网络通信是可靠的、有序的、差错控制的。TCP是面向连接的、可靠的流服务协议。TCP协议中,只有实现连接的双发才可以进行通信,因此广播和多播不是基于TCP的。下面首先介绍一些Socket和ServerSocket。
服务器、客户端建立通信的过程如下:

在这里插入图片描述在这里插入图片描述

  1. 服务器网络接口的IP地址为10.1.1.1。服务器端应用程序在80端口运行服务,建立ServerSocket,并监听有无连接请求。
  2. 客户端必须知道服务器的IP地址或主机名、服务开放端口,客户端向服务器的服务Socket(10.1.1.1:80)发起请求。
  3. 服务器一旦接收该请求,就会在80端口上建立一个Socket,该Socket的本地地址为10.1.1.1:80,外部地址为客户端建立的Socket(client端IP地址,client端port)。客户端port通常由操作系统指定。
  4. 服务器每接收一个客户端的请求,就会在服务端口上建立一个Socket,这些Socket的本地地址相同,但外部地址各不相同。每个外部地址即各个客户端的本地Socket。这样服务器既可以监听服务请求,又可以和每个客户端进行独立的通信。
  5. 客户端通过本地Socket与服务器进行通信、读写信息。就像打电话一样,一个号码呼叫另一个号码,一旦被呼叫者接听,通信链路就建立起来了,双方就可以通话了。

2. Socket类

2.1 Socket的通信过程

在这里插入图片描述在这里插入图片描述

2.2 控制Socket连接

获取Socket的输入流和输出流
服务端和客户端之间通信的Socket一旦连接,就会通过一对输入输出流进行通信。如同打电话时,一旦被叫放接听,双方通话的业务信道建立,就可以交流了。
Socket的getInputStream()方法和getOutputStream()方法分别实现获得输入流和输出流。

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new IntputStreamReader(socket.getInputStream()));

获取Socket的地址端口信息
如果需要获得本地或者远程Socket的地址和端口信息,可以使用以下方法:

getInetAddress() //获得远程服务器的IP地址
getPort() //获得远程服务器的端口
getLocalAddress() //获得客户端本地的IP地址
getLocalPort() //获得客户端本地的端口

关闭Socket
当客户端与服务器的通信结束时,应该关闭Socket,以释放Socket占用的包括

InputStream和OutputStream在内的各种资源。
if(!s.isClosed()) s.close();
//判断如果不是空的话则关闭

Socket的状态
Socket类提供了3中方法(isBound 、isClosed 和 isConnected)来判断Socket的状态。
isBound方法用来判断Socket的绑定状态,只要曾经绑定过,即使Socket已经关闭,仍然返回true。可以理解为本地是否曾经建立过到远程主机的Socket连接。
isClosed方法用来判断Socket是否已经关闭。
isConnected方法用来判断Socket的连接状态。和isBound方法一样,即使Socket已经关闭,仍然返回true,isConnected的状态不清楚。可以理解为到远程主机的Socket是否曾经连接过。

3. 基于TCP的BIO通信

3.1 实现功能

服务器创建服务并监听端口,与客户端建立连接,并向客户端转发消息,客户端输入quit命令即可退出。

3.2 程序源代码

Server类:

package com.company.bio;

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

public class Server {
    public static void main(String[] args){
        final  String QUIT = "quit";
        final int DEFAULT_PORT = 8888;
        ServerSocket serverSocket = null;

        //绑定监听端口
        try{
            serverSocket = new ServerSocket(DEFAULT_PORT);
            System.out.println("启动服务器,监听端口"+DEFAULT_PORT);

            while (true){
                // 等待客户端连接
                Socket socket = serverSocket.accept();
                System.out.println("客户端[" + socket.getPort() + "]已连接");
                //创建IO流
                BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(socket.getInputStream())
                );
                BufferedWriter bufferedWriter = new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())
                );

                String msg = null;
                while ((msg = bufferedReader.readLine()) != null) {
                    // 读取客户端发送的消息,当对方关闭时返回null

                    System.out.println("客户端["+socket.getPort()+"]:"+ msg);
                    //回复客户发送的消息
                    bufferedWriter.write("服务器:" + msg + "\n");
                    bufferedWriter.flush(); //保证缓冲区的数据发送出去
                    //查看客户端是否退出
                    if(QUIT.equals(msg)){
                        System.out.println("客户端["+socket.getPort()+"]已退出");
                        break;
                    }
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (serverSocket != null){
                try {
                    serverSocket.close();
                    System.out.println("关闭ServerSocket");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Client类:

package com.company.bio;

import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args)  {
        final  String QUIT = "quit";
        final String DEFAULT_SERVER_HOST = "127.0.0.1";
        final int DEFAULT_SERVER_PORT = 8888;
        Socket socket = null;
        BufferedWriter bufferedWriter = null;

        try{
            // 创建socket
            socket = new Socket(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
            //创建IO流
            BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(socket.getInputStream())
            );
            bufferedWriter = new BufferedWriter(
                 new OutputStreamWriter(socket.getOutputStream())
            );
            //等待用户输入信息
            BufferedReader consolReader = new BufferedReader(
                    new InputStreamReader(System.in)
            );
            while (true) {
                String input = consolReader.readLine();
                //发送消息给服务器
                bufferedWriter.write(input + "\n");
                bufferedWriter.flush();
                //读取服务器返回的消息
                String msg = bufferedReader.readLine();
                System.out.println(msg);

                //查看用户是否退出
                if(QUIT.equals(input))break;
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(bufferedWriter != null){
                try {
                    bufferedWriter.close();
                    System.out.println("关闭socket");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.3 程序效果截图
Client:

在这里插入图片描述在这里插入图片描述
Server:
在这里插入图片描述在这里插入图片描述

更多资源和教程请关注公众号:非科班的科班。
如果觉得我写的还可以请给个赞,谢谢大家,你的鼓励是我创作的动力

猜你喜欢

转载自www.cnblogs.com/liduchang/p/11778999.html
BIO