2015-03-19 70 views
0

我想实现类似下面的东西。有两台机器(比如他们的ips是A和B)监听固定端口上的数据(比如P和Q)。我希望他们在他们之间发送消息,而不必关心他是否在听。我查看套接字,但它遵循客户端服务器模式,这不符合我的要求。两台机器之间的Java网络通信

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

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?或者一些外部图书馆?

+0

如果其中一个没有在监听,那么试图发送消息的时候没有人会收到它? – vandale 2015-03-19 06:07:05

+0

我添加了一个解释。问题在于一台机器可能会超出wifi范围。如果它在范围内,我希望它收到消息。“ – 2015-03-19 06:10:10

回答

0

找到了如何使用DatagramChannelhttp://tutorials.jenkov.com/java-nio/datagram-channel.html的帮助下完成此操作。

以下是验证码。

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(); 
    } 
} 
相关问题