BIO

本文介绍了一种使用阻塞IO方式的ServerSocket与ClientSocket通信的实现方法,通过创建ServerSocket监听指定端口,接受客户端连接请求,并为每个连接创建新的线程进行处理。客户端通过Socket连接到服务器,发送请求并接收响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.简介
阻塞IO

2.ServerSocketDemo

public class BIOServerDemo {

    public static void main(String[] args) {
        ServerSocket server = null;
        try {
            server = new ServerSocket(8080);
            while (true) {
                Socket socket = server.accept();
                new Thread(new ServerHandler(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (server != null) {
                try {
                    server.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static class ServerHandler implements Runnable {
        private Socket socket;

        public ServerHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            BufferedReader bufferedReader = null;
            BufferedWriter bufferedWriter = null;
            try {
                bufferedReader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
                StringBuilder request = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    request.append(line);
                }
                System.out.println("request:" + request.toString());
                socket.shutdownInput();

                bufferedWriter = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
                bufferedWriter.write("response content.");
                bufferedWriter.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bufferedReader != null) {
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bufferedWriter != null) {
                    try {
                        bufferedWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

3.ClientSocketDemo

public class BIOClientDemo {

    public static void main(String[] args) {
        Socket socket = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            socket = new Socket("127.0.0.1", 8080);
            // request
            outputStream = socket.getOutputStream();
            outputStream.write("request content.".getBytes("utf-8"));
            outputStream.flush();
            socket.shutdownOutput();

            // response
            inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            StringBuilder response = new StringBuilder();
            int length;
            if ((length = inputStream.read(bytes)) != -1) {
                response.append(new String(bytes, 0, length));
            }
            System.out.println("response:" + response.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
### OpenSSL BIO 的概述 BIO 是 OpenSSL 中的一个核心组件,代表 **Basic I/O**。它提供了一种灵活的输入/输出机制,类似于标准 C 库中的文件操作接口 `FILE*`,但功能更强大且适用于多种场景[^1]。通过 BIO,可以实现对内存缓冲区、套接字连接以及加密数据流的操作。 以下是关于 OpenSSL BIO 的一些重要特性及其使用方法: --- ### 生物对象分类 BIO 对象分为两类: 1. **Source/Sink BIOs**: 这些 BIO 提供基本的数据源或目标(例如读取或写入)。常见的 Source/Sink BIO 包括: - 文件描述符 (`BIO_s_fd`) - 套接字 (`BIO_s_socket`) - 内存缓冲区 (`BIO_s_mem`) 2. **Filter BIOs**: 它们用于修改或处理数据流的内容。例如: - 加密解密过滤器 (`BIO_f_cipher`) - SSL/TLS 协议支持 (`BIO_f_ssl`) 这些类别可以通过链式结构组合起来形成复杂的 IO 流程[^2]。 --- ### 创建和管理生物对象实例 创建一个新的 BIO 实例通常涉及调用特定类型的构造函数。下面是一个简单的例子展示如何创建并销毁一个基于内存缓存的 BIO: ```c #include <openssl/bio.h> // 初始化一个指向内存区域的新BIO BIO *bio = BIO_new(BIO_s_mem()); if (!bio) { fprintf(stderr, "Failed to create memory BIO\n"); } else { const char message[] = "Hello from BIO!"; // 将字符串写入到该BIO中 int write_result = BIO_write(bio, message, strlen(message)); if (write_result != strlen(message)) { fprintf(stderr, "Write failed or incomplete.\n"); } unsigned char buffer[1024]; memset(buffer, 0, sizeof(buffer)); // 从BIO读回刚才写入的信息 int read_result = BIO_read(bio, buffer, sizeof(buffer)-1); printf("Read %d bytes: '%.*s'\n", read_result, read_result, buffer); // 清理资源 BIO_free_all(bio); } ``` 此代码片段展示了如何利用C语言编写程序来初始化一个内存型BIO,并执行基础的读写测试[^3]。 --- ### 链接多个BIO以构建复杂流程 由于 Filter 和 Source/Sink 可以串联在一起工作,因此能够轻松建立高级别的通信管道。比如要设置一个经过 AES 密码保护后再发送至远程服务器的消息传输过程,则可按如下方式配置: ```c const EVP_CIPHER *cipher_type = EVP_aes_256_cbc(); /* 使用AES-256-CBC */ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; /* ...填充key与iv... */ BIO *encrypt_bio = BIO_new(BIO_f_cipher()); BIO_set_cipher(encrypt_bio , cipher_type, key, iv, 1); // '1' 表明这是加密模式 BIO *socket_bio = BIO_new_connect("example.com:80"); // 替换为目标地址端口 if(!socket_bio || !BIO_do_connect(socket_bio)){ perror("Connection error:"); } BIO_push(encrypt_bio, socket_bio); // 把加密层叠加在网络连接之上 char plaintext[]="This is a secret."; int sent_bytes = BIO_write(encrypt_bio,plaintext,strlen(plaintext)+1); printf("%d Bytes were transmitted securely.",sent_bytes); ``` 这里我们先定义了一个采用指定算法进行加解密工作的 filter-BIO ,接着又准备好了实际负责网络交互的部分 source/sink-BIO 。最后把两者结合起来就实现了安全通道的效果[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值