我使用选择器运行套接字.我试图检查我的套接字是否连接到服务器.
Boolean connected = _channel.isConnected();
Run Code Online (Sandbox Code Playgroud)
它总是返回true.我关闭了计算机上的机场(互联网连接),当我检查套接字是否已连接时,它仍然返回true.知道为什么吗?我尝试每3秒向服务器写一次数据,但它仍然不会将我的套接字状态更改为断开连接.
我有一个服务器程序,需要关闭服务器关闭时剩余的所有连接。我知道我需要打电话SocketChannel.close()。我的问题是我是否还需要关闭与 关联的套接字,SocketChannel或者是否SocketChannel.close()自动关闭。
我的代码出了问题:我用Selector编写了简单的SocketChannel客户端,启动后成功从服务器读取消息(服务器发送事件).但是在写入socket(参见main方法)之后,选择器开始在infinyty循环中返回可读套接字,handleKey返回-1个字节的readed,因此选择器所有时间都返回OP_READ SelectionKey而没有数据用于读取.对不起我的英语不好.
谢谢.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class SelectorTest
{
public SelectorTest() throws IOException {
selector = Selector.open();
}
private void runSelector() {
new Thread(new Runnable() {
public void run()
{
alive = true;
try {
while(alive) {
System.out.println("Selector started...");
selector.select();
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while(keyIter.hasNext()) {
SelectionKey key = keyIter.next();
keyIter.remove();
handleKey(key);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}).start();
} …Run Code Online (Sandbox Code Playgroud) 我正在编写一个客户端服务器应用程序,我想从两个不同的线程(一个用于读取的线程,一个用于写入的线程)在一个套接字上读写。我的系统几乎可以正常工作,但是有一个令人困惑的错误,我似乎无法解决。阅读和写作相互独立的工作完美,但是当我开始从阅读Socket的OutputStream一个线程,写所有来电来InputStream在不同的线程块下去。
我编写了一个小型测试程序,用于快速重现该问题并消除尽可能多的外部变量。我使用java.nio的ServerSocketChannel和SocketChannel来建立连接,而我使用java.io的Socket(一个的基础套接字SocketChannel)则易于与ObjectInputStreamand 结合使用ObjectOutputStream。测试程序设计为运行两次;对于第一次运行,用户输入s以启动服务器,而在第二次运行中,用户输入c以运行客户端。
我的问题是:为什么objectOutput.writeObject( message );在该server()方法的第二次调用时执行以下程序块?(该方法的第四到最后一行)
我已经在程序代码下面列出了预期的输出和实际的输出以及我认为它们的含义。
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Scanner;
public class Main {
private static final String IP_ADDRESS = "localhost";
private static final int WELL_KNOWN_PORT = 4000;
public static …Run Code Online (Sandbox Code Playgroud) 我使用 SocketChannel 为 Android 编写了一个聊天应用程序。它与服务器成功连接并且所有功能都正常工作。但是在我登录后很长时间(大约 2-3 小时)后,我尝试再次发送聊天消息,但失败了。在日志文件中,SocketChannel,选择器仍然打开并连接到服务器,消息已经写入成功。有什么问题?我错过了什么?
在此先感谢您的帮助。
我在Java中构建了一个基于Selector的系统,可以接受多个客户端.它有一个在OP_ACCEPT下注册的ServerSocketChannel,它接受()s传入连接并再次向选择器注册生成的SocketChannel.这是位:
ServerSocketChannel insock = ServerSocketChannel.open();
insock.configureBlocking(false);
insock.socket().bind(new InetSocketAddress(6789));
Selector sel = Selector.open();
SelectionKey joinchannel = insock.register(sel, SelectionKey.OP_ACCEPT);
System.out.println("Ready to accept incoming connections.");
while (true) {
int ready = sel.selectNow();
if (ready == 0)
continue;
Set<SelectionKey> selectedKeys = sel.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if(key.isAcceptable()){
SocketChannel newConnection = insock.accept();
System.out.println("New client "+newConnection+" connected.");
newConnection.configureBlocking(false);
newConnection.register(sel, SelectionKey.OP_READ).attach(new DGPlayer());
}
Run Code Online (Sandbox Code Playgroud)
如果我为OP_READ注册新的SocketChannel,这可以正常工作.检查isReadable()成功,读取数据.这是位:
else if(key.isReadable()){
ByteBuffer buf = ByteBuffer.allocate(1024);
int trans = ((SocketChannel)key.channel()).read(buf); buf.flip();
byte[] ba = new byte[buf.remaining()]; …Run Code Online (Sandbox Code Playgroud) 我有一个简单的非阻塞服务器与主循环:
try {
while (selector.select() > -1) {
// Wait for an event one of the registered channels
// Iterate over the set of keys for which events are available
Iterator selectedKeys = selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
try {
if (!key.isValid()) {
continue;
}
if (key.isConnectable()) {
connect(key);
}
// Check what event is available and deal with it
if (key.isAcceptable()) {
accept(key);
}
if (key.isReadable()) {
read(key);
}
if (key.isWritable()) {
write(key);
} …Run Code Online (Sandbox Code Playgroud) 我有两个设计用于即时消息程序,我正在用Java编写
第一个想法使用2个单独的线程.第一个线程忽略了gui,并通过写入阻塞套接字发送即时消息数据.第二个线程使用另一个阻塞套接字来监视来自朋友的传入数据包.我不确定使用线程是否是解决此问题的最佳方法,但我发现它比使用非阻塞套接字通道更容易处理.
我的第二个设计是在一个线程中使用非阻塞套接字通道,偶尔会检查是否有传入或传出数据.这个设计的好处是我不必担心线程之间的资源共享,但我不确定它是否更有效.
老实说,我真正关心的是制作一个平稳有效的程序.您认为构建更高效,更容易的设计是什么?我只是在玩耍,所以我没有建立高效和强大的客户端/服务器程序的经验,而不是我的感官告诉我的.
如果在建立连接后的一段时间内没有收到数据,设置超时以关闭NIO SocketChannel的最佳方法是什么?
网络 4.0.24
我通过 UDP 传递 XML。当接收到UPD数据包时,数据包的长度始终为2048,从而截断了消息。尽管如此,我尝试将接收缓冲区大小设置为更大的值(4096、8192、65536),但它没有被兑现。
我已经使用另一种 UDP 摄取机制验证了 UDP 发送方。使用 java.net.DatagramSocket 的独立 Java 应用程序。XML 约为 45k。
我能够将堆栈跟踪到 DatagramSocketImpl.createChannel (第 281 行)。进入 DatagramChannelConfig,它的 receiveBufferSize 是我设置的(很好),但 rcvBufAllocator 为 2048。
rcvBufAllocator 是否会覆盖 receiveBufferSize (SO_RCVBUF)?消息是否来自多个缓冲区?
任何反馈或替代解决方案将不胜感激。
我还应该提到,我正在使用一个名为 vert.x 的 ESB,它大量使用 netty。由于我能够追踪到 netty,我希望能在这里找到帮助。