NIO发送数据过程:
1 将信道写入操作加锁保证其他线程不对信道写入(文档中称“是如果另一个线程已经在此通道上发起了一个写入操作,则在该操作完成前此方法的调用被阻塞。”)
2 如果缓冲区为非直接缓冲区,则复制缓冲区内容到直接缓冲区,防止外界对缓冲区内容修改导致发送数据损坏
* 复制过程分配的内存将被捆绑在线程上,在线程关闭之前,这部分内存不被回收,等IO操作完成后,可重用这部分内存,减少内存分配过程,其性能消耗更多在复制内容上。
* 直接缓冲区与非直接缓冲区参见ByteBuffer类文档
3 通过JNI调用本地方法直接将缓冲区地址和长度传递给操作系统,由系统进行异步IO操作
由此可见jvm与操作系统共用直接缓冲区。
MINA发送数据过程:
MINA发送数据过程在
org.apache.mina.core.polling.AbstractPollingIoProcessor.flushNow(T, long)
org.apache.mina.core.polling.AbstractPollingIoProcessor.writeBuffer(T, WriteRequest, boolean, int, long)
org.apache.mina.transport.socket.nio.NioProcessor.write(NioSession, IoBuffer, int)
方法中。
flashNow方法负责清空IoSession.writeRequestQueue列队。为保证传输效率,flashNow方法尽量将输出长度匹配到接收缓冲区长度的1.5倍。
flashNow方法循环调用writeBuffer,直到所调用writeBuffer方法返回值总和大于等于接收缓冲区容量的1.5倍、writeBuffer返回0或全部消息发送成功。
writeBuffer方法负责发送一条消息数据,write方法返回0,writeBuffer将连续尝试256次。
如果消息完整发送,将调用IoFilterChain.fireMessageSent(req)方法。如果有数据发送,将返回实际发送数据长度,否则返回0。
* 如果连接支持碎片拼接(如TCP连接),则writeBuffer方法可以决定输出消息的一部分,保证输出数据长度不超过输入缓冲区的1.5倍。
* 如果连接不支持碎片拼接(如UDP连接),则writterBuffer方法必须将消息完整输出。
write方法调用信道的write方法,将IoBuffer包装的ByteBuffer放入操作系统缓冲区,并返回结果。
由此可见,在基本NIO中,如果系统底层缓冲区填满,SocketChannel.write方法将返回0,业务逻辑必须处理此情况,否则将丢失发送数据。
在MINA中,使用消息分批或拆分方式将最大效率利用系统缓冲区,并保证由于系统缓冲区装满而未发送的消息将重新发送。
相关代码:
sun.nio.ch.SocketChannelImpl.write(ByteBuffer)关键代码:
.
.
.
for (;;) {
n = IOUtil.write(fd, buf, -1, nd, writeLock);
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
return IOStatus.normalize(n);
}
.
.
.
sun.nio.ch.IOUtil.write(FileDescriptor, ByteBuffer[], int, int, NativeDispatcher) 关键代码:
.
.
.
IOVecWrapper vec = IOVecWrapper.get(length);
.
.
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
hadow.put(buf);
shadow.flip();
vec.setShadow(iov_len, shadow);
.
.
.
long bytesWritten = nd.writev(fd, vec.address, iov_len);
SocketDispatcher.writev:
long writev(FileDescriptor fd, long address, int len) throws IOException {
return writev0(fd, address, len);
}
特殊返回值定义在:
final class IOStatus {
static final int EOF = -1; // End of file
static final int UNAVAILABLE = -2; // Nothing available (non-blocking)
static final int INTERRUPTED = -3; // System call interrupted
static final int UNSUPPORTED = -4; // Operation not supported
static final int THROWN = -5; // Exception thrown in JNI code
static final int UNSUPPORTED_CASE = -6; // This case not supported
static int normalize(int n) {
if (n == UNAVAILABLE)
return 0;
return n;
}
}
windows下JNI调用:
Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
{
/* set up */
int i = 0;
DWORD written = 0;
jint fd = fdval(env, fdo);
struct iovec *iovp = (struct iovec *)address;
WSABUF *bufs = malloc(len * sizeof(WSABUF));
if (bufs == 0) {
JNU_ThrowOutOfMemoryError(env, 0);
return IOS_THROWN;
}
if ((isNT() == JNI_FALSE) && (len > 16)) {
len = 16;
}
/* copy iovec into WSABUF */
for(i=0; i<len; i++) {
bufs[i].buf = (char *)iovp[i].iov_base;
bufs[i].len = (u_long)iovp[i].iov_len;
}
/* read into the buffers */
i = WSASend((SOCKET)fd, /* Socket */
bufs, /* pointers to the buffers */
(DWORD)len, /* number of buffers to process */
&written, /* receives number of bytes written */
0, /* no flags */
0, /* no overlapped sockets */
0); /* no completion routine */
/* clean up */
free(bufs);
if (i != 0) {
int theErr = (jint)WSAGetLastError();
if (theErr == WSAEWOULDBLOCK) {
return IOS_UNAVAILABLE;
}
JNU_ThrowIOExceptionWithLastError(env, "Vector write failed");
return IOS_THROWN;
}
return convertLongReturnVal(env, (jlong)written, JNI_FALSE);
}
windows本地接口
int WSASend (
SOCKET s,
LPWSABUF lpBuffers
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
返回值WSAEWOULDBLOCK Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as nonblocking and the send operation cannot be completed immediately.
分享到:
相关推荐
IoFilter接口定义了一组拦截器,用于实现如日志、黑名单过滤和数据编码解码等功能。数据的编码和解码是使用Mina时最核心的部分,因为它涉及到数据在网络中的传输格式。 IoHandler接口是编写业务逻辑的地方,接收和...
在本文中,我们将深入探讨Mina的高级使用,特别是在文件图片传送、文件发送、XML和JSON报文处理方面的实践。 1. **Mina的高级使用** Mina的核心在于其异步事件驱动的模型,这使得它在处理大量并发连接时表现出色。...
《Mina NIO Socket:深度解析与应用》 在Java世界中,网络编程是一个不可或缺的部分,而Mina NIO(Non-blocking I/O)Socket库则是Java开发者实现高性能、高并发网络服务的重要工具。本文将深入探讨Mina NIO Socket...
NIO (Non-blocking Input/Output) 和 MINA (Multipurpose Infrastructure for Network Applications) 是Java中用于高性能网络应用的两个重要框架。NIO是Java标准库的一部分,提供了与传统IO(Blocking I/O)不同的I/...
1. **非阻塞I/O**:MINA使用Java NIO(非阻塞I/O)库,这允许在单个线程中处理多个连接,极大地提高了系统资源的利用率和并发性能。 2. **事件驱动**:MINA基于事件驱动的设计,通过监听网络事件(如连接建立、数据...
`TestConnector.java`和`SocketTest.java`可能包含了此类客户端的示例代码,展示如何创建和管理Socket连接,以及发送和接收数据的基本流程。 相比之下,Mina NIO是一种基于Java NIO API的网络通信框架,它利用了多...
Java Mina是一个高性能、异步事件驱动的网络应用程序框架,主要用于简化开发服务器端和客户端的网络应用。这个“java mina组合包”看起来包含了Mina库的所有必要组件和可能的扩展,为开发者提供了完整的开发环境。 ...
在实际的通信过程中,客户端需要创建一个Socket连接到服务器的8080端口,然后通过SocketChannel发送和接收数据。服务器端接收到连接请求后,会创建一个IoSession,每个IoSession代表一个客户端连接。通过IoSession,...
它可能会继承自`java.nio.channels.ChannelHandler`或自定义的处理器接口,处理接收到的数据并发送时间信息回给客户端。 2. `MinaTimeServer.java`:Mina是一个开源的Java网络应用框架,它提供了一套高度可扩展的、...
Jetty、Tomcat和Mina都是Java领域中著名的Web服务器和应用服务器,它们在NIO架构上有着相似的设计模式。本文将从这三个框架中提炼出NIO构架网络服务器的经典模式,并逐一解析它们的核心机制。 首先,Jetty的NIO实现...
`NioSocketAcceptor`是Mina提供的非阻塞I/O(NIO)实现,它基于Java的`java.nio`包,能够高效地处理大量并发连接。 在`MinaTimeServer`中,`acceptor.getFilterChain()`用于构建过滤器链,这是Mina中的一个重要概念...
### Mina 2.0快速入门与源码解析 #### Mina 2.0 快速入门 Mina 2.0 是一个基于Java NIO技术的高效、可伸缩的网络通信框架,广泛应用于服务器端开发。Mina 2.0 的设计目标是为开发者提供一个易于使用的API,使得...
为了解决这一问题,可以采用Java NIO模型,并结合MINA框架来简化开发和提升性能。 MINA(Multipurpose Infrastructure for Network Applications)是一个开源的网络应用框架,为开发高性能、高可靠性的网络应用程序...
在Mina程序执行过程中,主要涉及以下几个关键步骤和组件: 1. **Acceptor 的建立**: Mina 提供了 `NioSocketAcceptor` 类来监听特定的端口,用于接收客户端的连接请求。`NioSocketAcceptor` 使用 Java NIO (非...
3. **MINA的时间服务器示例**:如何使用MINA搭建一个基础的时间服务器,包括创建服务端监听器、定义协议解码器和编码器、处理客户端连接请求和发送时间响应等步骤。 4. **多客户端处理**:MINA如何通过Selector和多...
1. **异步事件驱动模型**:MINA采用非阻塞I/O(NIO)模型,通过事件处理器(Event Handler)和事件驱动(Event Driven)模式,提高了处理大量并发连接的能力。 2. **统一API**:MINA提供了一个统一的API,无论使用...
这部分数据可能需要进一步解析,比如如果是IP数据,可能需要使用`java.net.InetAddress`和`java.net.SocketAddress`进行处理。 7. 检查FCS:虽然Java标准库没有提供内置的CRC计算功能,但你可以找到第三方库或者...
《mina-2.0.4源码解析:深入理解Java NIO通信框架》 Apache MINA(Multipurpose Infrastructure for Network Applications)是一个高度可扩展的、高性能的Java网络应用程序框架,主要用于构建服务器端应用。MINA...
2. 创建ProtocolDecoder与ProtocolEncoder:为了解析接收到的数据并编码要发送的数据,我们需要定义自定义的解码器和编码器。在文件传输中,可能需要处理文件的分块传输,所以解码器和编码器应能识别文件块边界。 3...
Mina(MINA,全称Java Minimal Asynchronous Network Library)是一个用Java开发的网络通信框架,主要用于简化网络应用的开发,尤其是TCP和UDP协议的应用。它提供了高度抽象的API,使得开发者可以更专注于业务逻辑,...