当前位置:   article > 正文

Java 网络编程之TCP(一):基于BIO

Java 网络编程之TCP(一):基于BIO

环境:

jdk 17

IntelliJ IDEA 2023.1.1 (Ultimate Edition)

Windows 10 专业版 22H2

TCP:面向连接的,可靠的数据传送协议

Java中的TCP网络编程,其实就是基于常用的BIO和NIO来实现的,本文先讨论BIO;

BIO:是JDK 1.4引入的网络编程模型,主要是指阻塞I/O编程模型

BIO中的阻塞体现在:

服务端:

服务器等待客户端连接的accept方法阻塞;

服务器读取客户端数据,等待数据准备好的阻塞;

客户端:

客户端读取服务器数据,等待数据准备好的阻塞;

服务端高并发:

既然服务端有阻塞,我们要想提高效率,得用多线程,一个负责处理一个客户端的业务数据;

同时,为了提高线程的使用效率,当一个客户端断开连接之后,该线程可以复用来处理其他线程;

获取一个线程负责多个客户端,进行轮询处理,这样就复杂些了;我们在其他文章中再讨论;

本文,我们使用最简单的方式,一个线程处理一个客户端数据,线程不复用;先把整个BIO的模型实现出来;

需求如下:基于BIO实现一个简单的服务端接收客户端的数据的网络模型;这个也是聊天室的基础;

服务端:可以接收多个客户端连接,通过字节流接收客户端发送的消息;服务端只接收,不发送

客户端:接收控制台输入的数据,然后通过字节流发送给服务端

服务端代码如下:

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. /**
  6. * 基于BIO的TCP网络通信的服务端,可以接收多个客户端连接,通过字节流接收客户端发送的消息;
  7. * 服务端只接收,不发送
  8. * 一个客户端需要使用一个线程
  9. * todo:线程资源复用
  10. *
  11. * @author freddy
  12. */
  13. class ChatServer {
  14. public static void main(String[] args) throws IOException {
  15. // 开启server 监听端口
  16. ServerSocket serverSocket = new ServerSocket(9999);
  17. while (true) {
  18. Socket client = serverSocket.accept(); // 阻塞操作,需要新的线程处理客户端
  19. // 接收Client数据,并转发
  20. new Thread(new ServerThread(client)).start();
  21. }
  22. }
  23. }
  24. /**
  25. * 服务端的线程,一个客户端对应一个
  26. */
  27. class ServerThread implements Runnable {
  28. Socket socket;
  29. public ServerThread(Socket socket) {
  30. this.socket = socket;
  31. }
  32. @Override
  33. public void run() {
  34. // 获取输入流程,读取用户输入
  35. // 持续接收Client数据,并打印
  36. System.out.println("server had a client" + socket);
  37. try (InputStream inputStream = socket.getInputStream()) {
  38. byte[] buffer = new byte[1024];
  39. int len;
  40. // read操作阻塞,直到有数据可读
  41. while ((len = inputStream.read(buffer)) != -1) {
  42. System.out.println("serer receive data from " + socket + " : " + new String(buffer, 0, len));
  43. }
  44. } catch (IOException e) {
  45. System.out.println(socket + " disconnect ");
  46. }
  47. }
  48. }

客户端代码如下:

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.io.OutputStream;
  4. import java.net.Socket;
  5. /**
  6. * 基于BIO的TCP网络通信的客户端,接收控制台输入的数据,然后通过字节流发送给服务端
  7. *
  8. * @author freddy
  9. */
  10. class ChatClient {
  11. public static void main(String[] args) throws IOException {
  12. // 连接server
  13. Socket serverSocket = new Socket("localhost", 9999);
  14. System.out.println("client connected to server");
  15. // 读取用户在控制台上的输入,并发送给服务器
  16. InputStream in = System.in;
  17. byte[] buffer = new byte[1024];
  18. int len;
  19. OutputStream outputStream = serverSocket.getOutputStream();
  20. // read操作阻塞,直到有数据可读
  21. while ((len = in.read(buffer)) != -1) {
  22. System.out.println("client receive data from console" + in + " : " + new String(buffer, 0, len));
  23. // 发送数据给服务器端
  24. outputStream.write(new String(buffer, 0, len).getBytes()); // 此时buffer中是有换行符
  25. }
  26. }
  27. }

测试:

先开启服务端;

然后开启两个客户端,在idea中需要打开Run -> Edit Configurations,选择我们的Application, 然后在右侧点击【Modify options】,选择【Allow multiple instances】,即可开启多个相同的Application ;

备注:不同版本的idea,选项位置可能有所不同

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/485856
推荐阅读
相关标签
  

闽ICP备14008679号