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

时间:2015-03-19 06:04:30

标签: java asynchronous network-programming nonblocking

我正在尝试实现以下内容。有两台机器(比如他们的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?还是一些外部库?

1 个答案:

答案 0 :(得分:0)

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();
    }
}