在socket InputStream读取数据的问题记录一文中介绍通过input.available()检测是否有可读的字节,上线之后发现服务器load过高,通过jstack发现大量线程都lock在在SocketInputStream.available()上,见截图:
之前以为input.available()会很耗时,通过打点发现原来是调用input.available()过于频繁导致:
解决这个问题有一个方案,不要调用input.available(),通过bufferInputStream不停的尝试read(),通过研究netty的代码发现有更好的方案,先检测input.available(),如果数据没有准备好,则挂起不占用cpu,这种方案是通过PushbackInputStream实现的:
public String readLine(int length) throws IOException { String buf = ""; PushbackInputStream input = new PushbackInputStream(socket.getInputStream(), 1); int index = 0; while (true) { index = buf.indexOf("\r\n"); if (index >= 0) { break; } int bytesToRead = Math.min(input.available(), length); if(bytesToRead>0){ byte[] data = new byte[bytesToRead]; input.read(data); String line = new String(data, Protocol.ENCODE); buf += line; }else{ int b = input.read(); //此操作会阻塞,直到有数据被读到 if (b < 0) { break; } input.unread(b); continue; } } return buf.substring(0, index); }
修复之后的情况:
后续发现还有问题:
相关推荐
深入剖析tomcat第三章SocketInputStream源码 * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/StringManager.java,v 1.2 2001/07/22 20:25:14 pier Exp $ * $Revision: 1.2...
Socket中的InputStream的`read`方法是Java网络编程中一个核心的概念,它在处理客户端与服务器之间的数据传输时起着至关重要的作用。`read`方法的阻塞特性是其设计的一个重要特点,也是理解多线程和并发编程的关键点...
SocketInputStream是Java编程语言中用于网络编程的一个重要组件,它属于Java套接字API的一部分,主要负责从套接字连接中读取字节流。在Unix和Linux操作系统环境下,网络编程通常涉及到进程间的通信,而Socket...
在Java编程中,`InputStream`是Java I/O流的基础类,用于从各种输入源读取数据。...对于压缩包中的`socketTest`文件,可能是用于测试网络数据传输的Socket编程示例,与`InputStream`在处理网络数据流时的应用紧密相关。
// 实现其他ServletInputStream的方法,如 available(), markSupported(), mark(int), reset() } } ``` 在这个例子中,我们创建了一个名为`RepeatableHttpServletRequest`的类,它继承自`...
例如,`FileInputStream`可以从文件系统读取数据,`SocketInputStream`可以从网络连接读取数据。在处理这些数据流时,可以利用`InputStream`提供的方法进行读取、跳过、标记和重置操作。 总结,`InputStream`在Java...
inputstream读取数据的问题,对你的file的帮组是很大的。
InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[1024]; int length = inputStream.read(buffer); String receivedData = new String(buffer, 0, length); // 处理接收到的数据...
`InputStream` 是所有字节输入流的父类,包括文件输入流 `FileInputStream`、内存输入流 `ByteArrayInputStream` 和网络输入流 `SocketInputStream` 等。通过继承 `InputStream`,子类可以实现特定类型的输入流,...
然而,使用Socket进行数据传输时,可能会遇到`read()`方法阻塞的问题,导致程序挂起,无法继续执行。为了解决这个问题,通常有以下三种策略: 1. **约定数据长度**: 在数据包的头部添加一个字段来指定数据的长度...
客户端则相反,它接收来自服务器的数据,通过Socket的InputStream读取,并用FileOutputStream将数据写入本地文件,从而实现文件的传输。 以下是实现这一过程的主要步骤: 1. **服务器端**: - 创建ServerSocket并...
- **关闭资源**:在完成数据交换后,应关闭Socket、InputStream和OutputStream,避免资源浪费。 9. **示例代码** - Server端示例: ```java ServerSocket serverSocket = new ServerSocket(12345); Socket ...
在Java中,它们是Java.io包下的基础类,提供了多种子类来处理不同类型的输出和输入操作,如`FileOutputStream`和`FileInputStream`用于文件操作,`SocketOutputStream`和`SocketInputStream`用于网络通信等。...
1. InputStream和OutputStream:Socket提供了InputStream和OutputStream的子类,如SocketInputStream和SocketOutputStream,用于读写网络数据。 2. BufferedReader和PrintWriter:通常使用BufferedReader读取Socket...
3. InputStream和OutputStream:Socket提供的InputStream和OutputStream是处理数据传输的基础。服务端和客户端可以通过这些流对象读写数据,实现双方的数据交换。 三、服务端实现 服务端程序主要包含以下步骤: 1. ...
通过Socket对象,我们可以获取InputStream,用来读取客户端发送的数据。常见的做法是使用BufferedReader配合InputStreamReader进行读取。 ```java InputStream clientInputStream = clientSocket.getInputStream(); ...
5. **关闭连接**:完成数据传输后,记得关闭所有打开的Socket和InputStream/OutputStream,以释放系统资源: ```java in.close(); out.close(); clientSocket.close(); forwardSocket.close(); serverSocket....
每次接收数据使用`Socket`的`InputStream`,如`Socket.getInputStream().read()`。 - 当接收完三次数据后,服务器可以将处理结果通过`Socket`的`OutputStream`写回给客户端。 2. **客户端实现:** - 创建`Socket`...
InputStream inputStream = socket.getInputStream(); DataInputStream dataInputStream = new DataInputStream(inputStream); // 读取服务器返回的数据 String serverResponse = dataInputStream.readUTF(); ...
InputStream inputStream = socket.getInputStream(); // 发送数据 outputStream.write("Hello, Server!".getBytes()); // 接收数据 int received = inputStream.read(); ``` 在Android中,还需要处理权限问题。在...