Byte[] 通过 SocketChannel 发送但未收到
Byte[] sent across SocketChannel but not received
我在处理一个需要一点网络的项目时遇到了一些麻烦,其中数据通过 SocketChannel
发送但从未收到。我能够通过一个简单的 localhost 聊天室程序重现该问题(如果有点乱,请见谅):
public class Main {
private Sender sender;
private Receiver receiver;
public static void main(String[] args) {
Main foo = new Main();
//The ports are switched in the other running version of this
foo.receiver = new Receiver("192.168.1.108", 12348);
foo.sender = new Sender("192.168.1.108", 12347);
foo.takeUserInput();
}
private void takeUserInput() {
while(true) {
System.out.println("Enter something");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = null;
try {
input = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sender.send(input);
}
}
}
public class Receiver implements Closeable {
private InetSocketAddress bindAddress;
private ServerSocketChannel server;
private ListenThread listenThread;
public Receiver(String address, int port) {
bindAddress = new InetSocketAddress(address, port);
bind();
listen();
}
public void bind() {
try {
server = ServerSocketChannel.open();
server.configureBlocking(true);
server.bind(bindAddress);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Bound to port " + bindAddress.getPort());
}
public void listen() {
listenThread = new ListenThread();
listenThread.start();
}
private class ListenThread extends Thread {
private SocketChannel client;
public void run() {
try {
client = server.accept();
System.out.println("Received connection from " + client.getLocalAddress());
} catch (IOException e) {
e.printStackTrace();
}
while((server.isOpen()) && (client.isOpen())) {
byte[] bytes = new byte[4096];
ByteBuffer buffer = ByteBuffer.wrap(bytes);
try {
System.out.println("Reading");
client.read(buffer);
System.out.println(new String(buffer.array()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
public void close() throws IOException {
server.close();
listenThread.client.close();
}
}
public class Sender implements Closeable {
private InetSocketAddress connectAddress;
private SocketChannel clientChannel;
public Sender(String address, int port) {
connectAddress = new InetSocketAddress(address, port);
connect();
}
public void connect() {
while((clientChannel == null) || (!(clientChannel.isConnected()))) {
try {
clientChannel = SocketChannel.open(connectAddress);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
System.out.println("Connected to " + clientChannel.getLocalAddress());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void send(String message) {
byte[] bytes = message.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(bytes);
try {
clientChannel.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Sent message");
}
@Override
public void close() throws IOException {
clientChannel.close();
}
}
这是一个版本的日志:
Bound to port 12348
Reading
Connected to /192.168.1.108:64699
Enter something
thing
Sent message
Enter something
另一个:
Bound to port 12347
Reading
Connected to /192.168.1.108:64698
Enter something
所以,我知道这两个程序都成功地建立了彼此的连接,并开始读取,但是当我从一端通过 SocketChannel 发送内容时,另一个程序仍然停留在 read()
调用 ListenThread
。
如何让客户端成功读取发送的内容?
我可以看到两个问题。
如@Ethan F 所述,端口不同。您应该使用相同的端口号。
您在 Receiver class 中的 listen()
方法永远不会被调用。您需要调用此方法接受连接。
foo.receiver = new Receiver("192.168.1.108", 12348);
foo.receiver.listen();
我在处理一个需要一点网络的项目时遇到了一些麻烦,其中数据通过 SocketChannel
发送但从未收到。我能够通过一个简单的 localhost 聊天室程序重现该问题(如果有点乱,请见谅):
public class Main {
private Sender sender;
private Receiver receiver;
public static void main(String[] args) {
Main foo = new Main();
//The ports are switched in the other running version of this
foo.receiver = new Receiver("192.168.1.108", 12348);
foo.sender = new Sender("192.168.1.108", 12347);
foo.takeUserInput();
}
private void takeUserInput() {
while(true) {
System.out.println("Enter something");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = null;
try {
input = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sender.send(input);
}
}
}
public class Receiver implements Closeable {
private InetSocketAddress bindAddress;
private ServerSocketChannel server;
private ListenThread listenThread;
public Receiver(String address, int port) {
bindAddress = new InetSocketAddress(address, port);
bind();
listen();
}
public void bind() {
try {
server = ServerSocketChannel.open();
server.configureBlocking(true);
server.bind(bindAddress);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Bound to port " + bindAddress.getPort());
}
public void listen() {
listenThread = new ListenThread();
listenThread.start();
}
private class ListenThread extends Thread {
private SocketChannel client;
public void run() {
try {
client = server.accept();
System.out.println("Received connection from " + client.getLocalAddress());
} catch (IOException e) {
e.printStackTrace();
}
while((server.isOpen()) && (client.isOpen())) {
byte[] bytes = new byte[4096];
ByteBuffer buffer = ByteBuffer.wrap(bytes);
try {
System.out.println("Reading");
client.read(buffer);
System.out.println(new String(buffer.array()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
public void close() throws IOException {
server.close();
listenThread.client.close();
}
}
public class Sender implements Closeable {
private InetSocketAddress connectAddress;
private SocketChannel clientChannel;
public Sender(String address, int port) {
connectAddress = new InetSocketAddress(address, port);
connect();
}
public void connect() {
while((clientChannel == null) || (!(clientChannel.isConnected()))) {
try {
clientChannel = SocketChannel.open(connectAddress);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
System.out.println("Connected to " + clientChannel.getLocalAddress());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void send(String message) {
byte[] bytes = message.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(bytes);
try {
clientChannel.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Sent message");
}
@Override
public void close() throws IOException {
clientChannel.close();
}
}
这是一个版本的日志:
Bound to port 12348
Reading
Connected to /192.168.1.108:64699
Enter something
thing
Sent message
Enter something
另一个:
Bound to port 12347
Reading
Connected to /192.168.1.108:64698
Enter something
所以,我知道这两个程序都成功地建立了彼此的连接,并开始读取,但是当我从一端通过 SocketChannel 发送内容时,另一个程序仍然停留在 read()
调用 ListenThread
。
如何让客户端成功读取发送的内容?
我可以看到两个问题。
如@Ethan F 所述,端口不同。您应该使用相同的端口号。
您在 Receiver class 中的
listen()
方法永远不会被调用。您需要调用此方法接受连接。foo.receiver = new Receiver("192.168.1.108", 12348); foo.receiver.listen();