我试图了解SocketChannels和NIO.我知道如何使用常规套接字以及如何创建一个简单的每个客户端线程服务器(使用常规阻塞套接字).
所以我的问题:
A selectable channel for stream-oriented connecting sockets..那是什么意思?我已经阅读了这个文档,但不知怎的,我没有得到它...
我正在玩NIO库.我正在尝试在端口8888上侦听连接,一旦接受连接,就从该通道转储所有内容somefile.
我知道该怎么做ByteBuffers,但我想让它与所谓的超高效工作FileChannel.transferFrom.
这就是我得到的:
ServerSocketChannel ssChannel = ServerSocketChannel.open();
ssChannel.socket().bind(new InetSocketAddress(8888));
SocketChannel sChannel = ssChannel.accept();
FileChannel out = new FileOutputStream("somefile").getChannel();
while (... sChannel has not reached the end of the stream ...) <-- what to put here?
out.transferFrom(sChannel, out.position(), BUF_SIZE);
out.close();
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:如何表达" transferFrom某个频道,直到到达流末端"?
编辑:将1024更改为BUF_SIZE,因为所使用的缓冲区大小与问题无关.
我想使用a SocketChannel和它的读/写方法超时.我试图设置一个拥有我SocketChannel喜欢的Socket的超时:
channel.socket().setSoTimeout(TIMEOUT);
Run Code Online (Sandbox Code Playgroud)
但这不起作用.还有其他解决方案吗?
理想情况下,我只需要一个简单的SSLSocketChannel.
我已经有一个组件可以读取和写入普通的消息SocketChannel,但对于其中一些连接,我必须通过线路使用SSL; 但是,这些连接上的操作是相同的.
有没有人知道一个免费的SSLSocketChannel实现(使用适当的选择器)或类似的东西?我发现了这个,但选择器不接受它,因为它的供应商不是SUN.
我正在通过一个简单的对象将read_from/writing_to网络逻辑与网络数据的插入和检索分离,以便使用SSLEngine而不会生气,但考虑到我不知道的事实,实现它是非常棘手的SSL协议的内部......
如何使用TLS 保护Java SocketChannel,ServerSocketChannel或者甚至是a DatagramChannel?
这是一个非常直截了当的问题,但我发现需要取消注册选择器,忽略我的套接字通道的java.
SocketChannel client = myServer.accept(); //forks off another client socket
client.configureBlocking(false);//this channel takes in multiple request
client.register(mySelector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);//changed from r to rw
Run Code Online (Sandbox Code Playgroud)
我可以在以后的程序中调用类似的东西
client.deregister(mySelector);
Run Code Online (Sandbox Code Playgroud)
并且选择器将不再捕获该套接字通道的数据键.鉴于我的服务器/客户端设计,这将使我的生活更轻松.
我想使用 Kotlin(v1.3.0)协程和 java.nio.channels。SocketChannel (NIO) 来替代connectAndroid 中的Socket (阻塞 IO)。因为这可以节省很多线程。
下面的代码因为job.await()在 Kotlin 中挂起函数而无法运行,它只能在 Ktolin 协程块中调用。喜欢launch{..},async{..}。
// this function will be called by Java Code
fun connect(address: InetSocketAddress, connectTimeout: Int): SocketChannel {
// Start a new connection
// Create a non-blocking socket channel
val socketChannel = SocketChannel.open()
socketChannel.configureBlocking(false)
// async calls NIO connect function
val job = GlobalScope.async(oneThreadCtx) {
aConnect(socketChannel, address)
}
// I what to suspend(NOT block) current Java Thread, until …Run Code Online (Sandbox Code Playgroud) 我目前正在使用非阻塞SocketChannel(Java 1.6)充当Redis服务器的客户端.Redis直接在套接字上接受纯文本命令,由CRLF终止并以类似方式响应,这是一个简单的例子:
发送:'PING\r \n'
RECV:'+ PONG\r \n'
Redis还可以返回大量回复(取决于您要求的内容),其中许多\ r \n终止数据部分都作为单个响应的一部分.
我使用标准while(socket.read()> 0){// append bytes}循环从套接字读取字节并将它们重新组装到客户端进行回复.
注意:我没有使用Selector,只是连接到服务器的多个客户端SocketChannel,等待服务发送/接收命令.
我感到困惑的是合同中的SocketChannel.read()在非阻塞模式的方法,特别是如何知道什么时候该服务器进行发送,我有整个邮件.
我有一些方法可以防止返回太快并让服务器有机会回复,但我坚持的一件事是:
基本上,如果我收到至少1个字节并且最终read()返回0然后我知道我已经完成了,或者可能服务器只是忙碌而且可能会丢弃一些如果我等待并继续尝试更多的字节?
如果它仍然可以继续发送字节,即使read()返回0字节(之前成功读取后),那么我不知道如何告诉服务器何时完成与我交谈,事实上我很困惑如何java.io.*样式通信甚至可以知道服务器何时"完成".
你们知道read永远不会返回-1,除非连接已经死了,这些都是标准的长期数据库连接,所以我不会在每次请求时关闭并打开它们.
我知道一个受欢迎的反应(至少对于这些NIO问题)一直在看Grizzly,MINA或Netty - 如果可能的话,我真的想在采用第三方依赖之前了解这一切是如何工作的.
谢谢.
奖金问题:
我原本以为阻塞SocketChannel就是这样的方式,因为我不想让调用者做任何事情,直到我处理他们的命令然后给他们回复.
如果这最终成为一种更好的方法,只要没有足够的字节来填充给定的缓冲区,我就会看到SocketChannel.read()阻塞,我有点困惑...没有逐字节读取所有内容我无法弄清楚这个默认行为是如何实际使用的......我从来不知道从服务器返回的回复的确切大小,所以我对SocketChannel.read()的调用总是阻塞直到超时(此时我终于看到内容位于缓冲区中了.
我不清楚使用阻塞方法的正确方法,因为它总是挂起来读取.
我使用选择器运行套接字.我试图检查我的套接字是否连接到服务器.
Boolean connected = _channel.isConnected();
Run Code Online (Sandbox Code Playgroud)
它总是返回true.我关闭了计算机上的机场(互联网连接),当我检查套接字是否已连接时,它仍然返回true.知道为什么吗?我尝试每3秒向服务器写一次数据,但它仍然不会将我的套接字状态更改为断开连接.
我有一个服务器程序,需要关闭服务器关闭时剩余的所有连接。我知道我需要打电话SocketChannel.close()。我的问题是我是否还需要关闭与 关联的套接字,SocketChannel或者是否SocketChannel.close()自动关闭。
socketchannel ×10
java ×9
nio ×4
sockets ×4
nonblocking ×2
ssl ×2
android ×1
channel ×1
filechannel ×1
kotlin ×1
networking ×1
okhttp ×1
select ×1
sslengine ×1