Java 两台机器之间的网络通信

Java Network Communication Between two machines

我正在尝试实现如下内容。有两台机器(比如它们的 ips 是 A 和 B)在固定端口(比如 P 和 Q)上监听数据。我希望他们在他们之间发送消息,而不用关心是否有人在听。我查看了套接字,但它遵循不符合我要求的客户端服务器模式。

例如我正在寻找的是这样的东西。

B 执行以下操作

Communicator c = new Communicator(A,P); //does not block
c.write(byteArray); //does not block

while(true)
{
    if(c.hasData())
    {
        bytes[] bytes = c.readData();
    }
}

A也一样。比如A和B在一个循环内的不同线程读写,不关心另一端是否接收到数据。

更多解释:问题是一台机器可能超出wifi范围。如果它在范围内,我希望它能收到消息。

我想你可能会说我正在尝试在没有服务器的情况下在两台机器和已知端口之间进行通信。

java 中是否有我可以用于此目的的 API?或者一些外部图书馆?

http://tutorials.jenkov.com/java-nio/datagram-channel.html 的帮助下找到了 DatagramChannel 的使用方法。

代码如下

import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.StandardCharsets;

public class ReaderThread extends Thread {

    private DatagramChannel channel;

    public ReaderThread(DatagramChannel channel) {
        this.channel = channel;
    }

    @Override
    public void run() {
        try {
            ByteBuffer packet = ByteBuffer.allocate(65536);
            while (true) {
                packet.clear();
                if (channel.receive(packet) != null) {
                    packet.flip();
                    int remaining = packet.remaining();
                    byte[] b = new byte[remaining];
                    packet.get(b, 0, remaining);
                    System.out.println(new String(b, StandardCharsets.UTF_8));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.StandardCharsets;

public class WriterThread extends Thread {
    private SocketAddress target;
    private DatagramChannel channel;

    public WriterThread(DatagramChannel channel, int othersPort, String othersIp) {
        super();
        this.target = new InetSocketAddress(othersIp, othersPort);
        this.channel = channel;
    }

    @Override
    public void run() {
        try {
            while (true) {
                ByteBuffer buf = ByteBuffer.allocate(48);
                buf.clear();
                buf.put("Hello world!".getBytes(StandardCharsets.UTF_8));
                buf.flip();
                channel.send(buf, target);
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;

public class Main {
    public static void main(String[] args) throws IOException {
        int portA = 1091;
        String machineA = "localhost";// "10.101.2.40";
        int portB = 1092;
        String machineB = "localhost";// "10.101.2.39";

        DatagramChannel channelA = DatagramChannel.open();
        channelA.socket().bind(new InetSocketAddress(portA));
        channelA.configureBlocking(false);
        ReaderThread readerA = new ReaderThread(channelA);
        WriterThread writerA = new WriterThread(channelA, portB, machineB);
        readerA.start();
        writerA.start();

        DatagramChannel channelB = DatagramChannel.open();
        channelB.socket().bind(new InetSocketAddress(portB));
        channelB.configureBlocking(false);
        ReaderThread readerB = new ReaderThread(channelB);
        WriterThread writerB = new WriterThread(channelB, portA, machineA);
        readerB.start();
        writerB.start();
    }
}