gpt4 book ai didi

Java NIO 套接字 : the server doesn't receive the second message over the same socket

转载 作者:太空宇宙 更新时间:2023-11-04 09:15:42 24 4
gpt4 key购买 nike

我有使用 Java NIO 套接字构建的简单服务器和客户端。这个想法是客户端发送 5 到服务器,服务器回复 1。然后,客户端使用相同的套接字再次发送 1,服务器应再次回复 5

但是,服务器没有收到第二条消息。这是我的实现:

服务器.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;

public class Server {

public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(4444));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
if (selector.select() > 0) {
for (SelectionKey key : selector.selectedKeys()) {
if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1);
clientChannel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
clientChannel.write(ByteBuffer.wrap(new byte[]{1}));
System.out.println("Replied: 1");
}
if (key.isAcceptable()) {
SocketChannel channel = serverChannel.accept();
if (channel != null) {
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
System.out.println("Accepted");
}
}
}
}
}
}
}

Client.java

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class Client {

public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 4444));
sc.register(selector, SelectionKey.OP_CONNECT);

while (true) {
if (selector.select() > 0) {
for (SelectionKey key : selector.selectedKeys()) {
SocketChannel channel = (SocketChannel) key.channel();
if (key.isConnectable()) {
while (channel.isConnectionPending()) {
channel.finishConnect();
}
key.interestOps(SelectionKey.OP_WRITE);
System.out.println("Connected");
}
if (key.isWritable()) {
channel.write(ByteBuffer.wrap(new byte[] { 5 }));
key.interestOps(SelectionKey.OP_READ);
System.out.println("Sending: 5");
}
if (key.isReadable()) {
ByteBuffer buffer = ByteBuffer.allocate(1);
channel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
key.interestOps(SelectionKey.OP_WRITE);
}
}
}
}
}
}

服务器输出

Accepted
Received: 5
Replied: 1

客户端输出

Connected
Sending: 5
Received: 1
Sending: 5

最佳答案

我在这里找到了问题的解决方案:https://stackoverflow.com/a/9940133/4167198

select() returns the number of keys that have changed. So if a key was already ready before the select() call then it could return 0 but selectedKeys could be non-empty.

因此不需要检查 select() 返回的值是否大于 0。

服务器.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;

public class Server {

public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(4444));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1);
clientChannel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
clientChannel.write(ByteBuffer.wrap(new byte[]{1}));
System.out.println("Replied: 1");
}
if (key.isAcceptable()) {
SocketChannel channel = serverChannel.accept();
if (channel != null) {
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
System.out.println("Accepted");
}
}
}
}
}
}

Client.java

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class Client {

public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 4444));
sc.register(selector, SelectionKey.OP_CONNECT);

while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
SocketChannel channel = (SocketChannel) key.channel();
if (key.isConnectable()) {
while (channel.isConnectionPending()) {
channel.finishConnect();
}
key.interestOps(SelectionKey.OP_WRITE);
System.out.println("Connected");
}
if (key.isWritable()) {
channel.write(ByteBuffer.wrap(new byte[] { 5 }));
key.interestOps(SelectionKey.OP_READ);
System.out.println("Sending: 5");
}
if (key.isReadable()) {
ByteBuffer buffer = ByteBuffer.allocate(1);
channel.read(buffer);
System.out.println("Received: " + buffer.array()[0]);
key.interestOps(SelectionKey.OP_WRITE);
}
}
}
}
}

关于Java NIO 套接字 : the server doesn't receive the second message over the same socket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59034754/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com