`

利用Pipe实现最简单的通信

阅读更多

本文主要讲解的是如何单纯发布管道广告,及利用发现的管道进行简单的信息通信。PeerServer发布管道广告,等待其它PeerClient发现及连接,然后向PeerServer发送一条内容为“你是谁”的信息。下面给出的两个类可以放在同个目录下运行。

public class PeerServer {

 private DiscoveryService discoveryService = null;

 private PipeService pipeService = null;

 private PeerGroup restoNet = null;

 private PeerGroupID peerGroupID = null;

 private InputPipe inputPipe = null;


 public static void main(String[] args) {
  Logger.getLogger("net.jxta").setLevel(Level.SEVERE);
  PeerServer peer1 = new PeerServer();
  peer1.launchJXTA();
 }

 private void launchJXTA() {
  try {
   NetworkConfigurator config = new NetworkConfigurator();//设置配置可以跳过第1次运行时出现的配置UI
   config.setPrincipal("peer1");// Peer名称
   config.setPassword("888888888");// Peer密码
   config.save();
   restoNet = new NetPeerGroupFactory().getInterface();
   peerGroupID = restoNet.getPeerGroupID();
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(-1);
  }
  discoveryService = restoNet.getDiscoveryService();// 取得NetPeerGroup的发现服务
  pipeService = restoNet.getPipeService();// 取得NetPeerGroup的管道服务
  startServer();// 开始启动
 }

 private void startServer() {
  publishPipeAdvertisement();// 发布管道广告
 }
 //创建及发布管道广告
 private void publishPipeAdvertisement() {
  PipeAdvertisement pipeAdv = createPipeAdvertisement();
  // -----------------以下这段代码只是为了把管道广告的内容打印出来--------------------------
  StructuredTextDocument doc = (StructuredTextDocument) pipeAdv
    .getDocument(MimeMediaType.XMLUTF8);
  StringWriter out = new StringWriter();
  try {
   doc.sendToWriter(out);
   System.out.println(out.toString());
   out.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
  // -----------------------------打印结束--------------------------------------------
  try {
   discoveryService.publish(pipeAdv);//本地发布管道广告
   discoveryService.remotePublish(pipeAdv);//远程发布管道广告
   inputPipe = pipeService.createInputPipe(pipeAdv);// 创建输入管道
  } catch (IOException e) {
   e.printStackTrace();
  }
  while (true) {
   System.out.println("等待其它Peer端信息的到达.........");
   Message msg;
   try {
    msg = inputPipe.waitForMessage();// 监听输入管道是否有信息传进来
   } catch (InterruptedException e) {
    inputPipe.close();
    System.out.println("接收其它Peer信息出错!");
    return;// 如果出现异常则返回
   }
   String receiveContent = null;
   Message.ElementIterator en = msg.getMessageElements();// 取得到信息
   if (!en.hasNext()) {
    return;
   }
   MessageElement msgElement = msg.getMessageElement(null, "DataTag");
   if (msgElement.toString() != null) {
    receiveContent = msgElement.toString();
   }
   if (receiveContent != null) {
    System.out.println("接收信息内容: "
      + receiveContent);
   } else {
    System.out
      .println("没有内容");
   }
  }
 }

 // 生成管道广告,在这里我们是直接从代码中生成管道广告,当然我们可以读管道广告文件
 private PipeAdvertisement createPipeAdvertisement() {
  PipeAdvertisement pipeAdvertisement = null;
  pipeAdvertisement = (PipeAdvertisement) AdvertisementFactory
    .newAdvertisement(PipeAdvertisement.getAdvertisementType());// 创建一个管道广告
  pipeAdvertisement.setPipeID(createPipeID(peerGroupID));
  pipeAdvertisement.setName("Pipe");
  pipeAdvertisement.setDescription("JXTA create first pipe");
  pipeAdvertisement.setType(PipeService.UnicastType);// 管道类型,管道类型在JXTA
  return pipeAdvertisement;
 }

 // 生成管道ID
 private PipeID createPipeID(PeerGroupID groupID) {
  PipeID pipeID = null;
  pipeID = IDFactory.newPipeID(groupID);
  return pipeID;
 }
}
先执行上面这个类,再执行下面PeerClient类。

public class PeerClient {

 private PeerGroup netpg = null;// PeerGroup

 private DiscoveryService disco; // 发现服务

 private PipeService pipeSev; // 管道服务

 private PipeAdvertisement pipeAdv = null;// 管道广告

 private OutputPipe outputPipe;// 输入管道

 public static void main(String[] args) {
  Logger.getLogger("net.jxta").setLevel(Level.SEVERE);
  PeerClient peer2 = new PeerClient();
  peer2.launchJXTA();
 }

 private void launchJXTA() {
  System.out.println("Lauching Peer into JXTA NetWork...");
  try {
   NetworkConfigurator config = new NetworkConfigurator();
   config.setPrincipal("peer2");
   config.setPassword("888888888");
   config.save();
   netpg = new NetPeerGroupFactory().getInterface();
  } catch (Exception e) {
   System.out.println("Unable to create PeerGroup - Failure");
   System.exit(-1);
  }
  startClient();
 }

 private void startClient() {
  System.out.println("搜索管道广告....");
  disco = netpg.getDiscoveryService();//获取NetGroup发现服务
  pipeSev = netpg.getPipeService();//获取NetGroup管道服务
  Enumeration en;
  while (true) {
   try {
    en = disco.getLocalAdvertisements(DiscoveryService.ADV, "Name",
      "Pipe");// 本地发现广告,后面对应了广告中Name标签,值为Pipe的管道广告
    if ((en != null) && en.hasMoreElements()) {
     break;
    }
    disco.getRemoteAdvertisements(null, DiscoveryService.ADV,
      "Name", "Pipe", 1, null);// 远程发现广告
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
   System.out.print(".");
  }
  System.out.println("已经找到管道广告.......");
  pipeAdv = (PipeAdvertisement) en
  .nextElement();
  if (null == pipeAdv) {
   System.out.println("没有找到管道广告");
  }
  try {
   outputPipe = pipeSev.createOutputPipe(pipeAdv, 10000);// 创建输出管道,其实是连接Peer1中的输入管道
  } catch (IOException e) {
   e.printStackTrace();
  }
  String data = "你是谁";// 我们要发送的信息内容
  Message msg = new Message();

  StringMessageElement sme = new StringMessageElement("DataTag", data,
    null);
  msg.addMessageElement(null, sme);
  try {
   outputPipe.send(msg);// 发送信息
   System.out.println("信息 \"" + data
     + "\" 已经发送");
  } catch (IOException e) {
   e.printStackTrace();
   System.out
     .println("发送信息失败!!");
  }

 }

}

0
0
分享到:
评论
9 楼 A11819 2012-11-16  
heyiwen871220 写道
Output Pipe could not be resolved after 10000ms.我也是这个错误。。。高手,指点下吧...555

我也发现了这个问题,第一次启动可以成功,第二次就报错了。我是把项目文件夹下面的".jxta"文件夹删除了再启动就好了,现在还没弄清楚到底什么原因。
8 楼 heyiwen871220 2011-11-23  
Output Pipe could not be resolved after 10000ms.我也是这个错误。。。高手,指点下吧...555
7 楼 leigous 2011-04-20  
lyndon.lin 写道
你所谓的远程是指?那种,网络的,还是只是不同机的。不过经过其他人测试说,直接这个说远程连接不上,要用标准的方法来连接。即把管道广告包含在实现广告中发布。

实现广告是什么意思?
6 楼 leigous 2011-04-19  
你好我用你上面的两个程序进行了测试,第一运行能成功,当我关了PeerServer再开时,运行PeerClient就会出现
Lauching Peer into JXTA NetWork...
搜索管道广告....
已经找到管道广告.......
java.io.IOException: Output Pipe could not be resolved after 10000ms.
        at net.jxta.impl.pipe.PipeServiceImpl.createOutputPipe(PipeServiceImpl.java:459)
        at net.jxta.impl.pipe.PipeServiceImpl.createOutputPipe(PipeServiceImpl.java:416)
        at net.jxta.impl.pipe.PipeServiceInterface.createOutputPipe(PipeServiceInterface.java:160)
        at jxta_comunication.PeerClient.startClient(PeerClient.java:84)
        at jxta_comunication.PeerClient.launchJXTA(PeerClient.java:51)
        at jxta_comunication.PeerClient.main(PeerClient.java:36)
Exception in thread "main" java.lang.NullPointerException
        at jxta_comunication.PeerClient.startClient(PeerClient.java:95)
        at jxta_comunication.PeerClient.launchJXTA(PeerClient.java:51)
        at jxta_comunication.PeerClient.main(PeerClient.java:36)
应该就是Output连不上了。请问这是什么问题?
5 楼 lifeng_2009 2010-06-03  
lyndon.lin 写道
你所谓的远程是指?那种,网络的,还是只是不同机的。不过经过其他人测试说,直接这个说远程连接不上,要用标准的方法来连接。即把管道广告包含在实现广告中发布。

你好 我也通过你提示我的信息找了相关的资料,其中 即把管道广告包含在实现广告中发布。 我做了测试 这种情况只有两端都建立默认组的情况下才能实现。如果一方建立组 另外一方加入此组 就找不到PipeAdvertisement. 也不知道是什么情况导致的。难道两个PEER在默认组 和两个PEER在自己建立的peergroup 是不一样的、
4 楼 lyndon.lin 2010-05-28  
发现RDV其实是需要通过设定Seed来做的  要不然外网的RDV是无法发现:
config.addSeedRelay(new URI("http://192.168.0.9:9702"),10);
config.addSeedRendezvous(new URI("http://192.168.0.9:9702"),10);
3 楼 lifeng_2009 2010-05-28  
你好;
     可能是我说的不太清楚,我用你的例子在一个远程服务器上建立了服务端,也就是你写的PEERSERVER类 在服务端运行
我的客户端是在我公司的子网里面 现在在子网运行你的PEERCILENT类时 互相都搜索不到对方。
     另外像你这样的用代码跳过配置窗口。不用给服务器端配置Rendezvous 让服务器作为Rendezvous吗
我关于JXTA配置窗口的配置如下 不知道对不对 请牙哥指点下
服务器设置 在Basic 中 填写 peername 和 password
         在 Advanced 中把服务器设置为 Act as a Rendezvous
                  TCP Settings中 给Manual设置自己的IP 加9701端口
          在Rendezvous/Relays中 取消Use a rendezvous 和 Use a relay复选框
客户端设置
        在Basic 中 填写 peername 和 password
        在 Advanced 中 什么都不改
          在Rendezvous/Relays中
                    在 Use a rendezvous 的 Rendezvous seed peers中填写
                      tcp://服务器IP:9701 
                    取消 Use a relay复选框
我现在不清楚要是连接远程服务器是不是我配置的有问题。
你说的:“要用标准的方法来连接。即把管道广告包含在实现广告中发布。”
的标准方法连接是什么意思 普通连接是什么呢 。后面的意思有是什么呢?
我们平时发布广告不是用
DiscoveryService.publish 来发布本地广告
DiscoveryService.remotePublish  来发布远程广告
你说的实现广告中发布是什么意思呢?
                     
2 楼 lyndon.lin 2010-05-27  
你所谓的远程是指?那种,网络的,还是只是不同机的。不过经过其他人测试说,直接这个说远程连接不上,要用标准的方法来连接。即把管道广告包含在实现广告中发布。
1 楼 lifeng_2009 2010-05-27  
远程不通啊!

相关推荐

    管道机制实现进程间的通信

    本实验旨在通过实践操作,帮助学习者深入理解管道的工作原理及其应用,并掌握如何使用管道来实现进程间的简单通信。 #### 实验内容 ##### 1. 了解系统调用`pipe()`的功能和实际原理 在Linux系统中,`pipe()`是一...

    电子科大操作系统实验课Linux通过管道实现进程间通信

    - 管道是Linux操作系统中的一种简单但有效的进程间通信(IPC, Inter-Process Communication)机制,它允许一个进程的输出作为另一个进程的输入。 - 在这个实验中,通过`pipe()`系统调用创建了一个单向的数据通道,...

    进程间使用管道通信pipe.doc

    其中,管道(pipe)作为一种最简单且高效的方式之一,被广泛应用于Unix及类Unix操作系统中。本文档将详细介绍如何使用管道来实现进程间的通信。 #### 二、基础知识 **1. 管道的概念** - **定义**:管道是一种特殊...

    UNIX 操作系统基础实验 - 利用管道实现两个进程的通信.pdf

    通过这个实验,学生可以深入理解进程间通信的重要性,以及如何利用管道这种简单的IPC机制实现数据传输。此外,实验也涉及到进程同步的概念,例如父进程等待子进程完成后再继续执行,这确保了数据正确地按顺序写入和...

    匿名管道实现进程间通信示例程序

    匿名管道是操作系统提供的一种简单而基础的进程间通信(IPC, Inter-Process Communication)机制,尤其在早期的Unix系统和Windows系统中广泛应用。本示例程序将深入探讨如何使用匿名管道来实现两个进程之间的数据...

    进程间通信案例

    1. **管道(Pipe)**:管道是简单的单向通信通道,允许一个进程写入数据,另一个进程读取。在聊天应用中,可以利用管道传递用户的聊天消息到服务器,但不适用于两个客户端间的直接通信。 2. **消息队列(Message ...

    IPC进程通信

    7. **信号(Signal)**:信号是一种简单的进程间通信方式,用于通知进程发生了特定事件,如异常或者需要进程执行某些操作。 ### IPC 的应用场景 - **协同工作**:当多个进程需要协作完成一项任务时,例如一个进程...

    linux进程间通信.pdf

    1. **管道(Pipe)**:最简单的一种IPC方式,用于实现父子进程间的通信,具有单向性。 2. **有名管道(FIFO)**:与管道类似,但是具有名字,可以跨进程使用。 3. **信号(Signal)**:用于通知接收进程发生某些类型...

    进程通信实例源代码技术资料

    - **资源利用**:通过进程通信,进程可以共享数据,提高资源利用率,避免重复计算。 - **协同工作**:进程间通信使得多进程能协调执行,解决复杂问题,如分布式计算、并发服务等。 - **系统效率**:通过合理设计...

    操作系统课程设计进程间通信

    无名管道是最简单的IPC形式,通常用于父子进程之间的通信。它是一个半双工的通信通道,数据只能单向流动。创建时,管道连接在父进程与子进程之间,当父进程创建子进程后,它们可以通过管道共享数据。 **有名管道...

    进程间通信之管道通信

    本文将详细介绍一个基于管道通信的示例程序,该程序由一个父进程和两个子进程组成,展示了如何利用管道来实现进程间的通信。 #### 二、示例程序解析 ##### 2.1 程序结构 示例程序通过C语言编写,主要包括以下部分...

    linux进程间通信详解

    管道适用于父子进程或兄弟进程之间的简单通信。 二、命名管道(Named Pipe) 与普通管道不同,命名管道可以在不具有亲缘关系的进程之间使用,因为它在文件系统中有一个固定的路径名。通过这个路径,任何有权限的...

    window进程间通信(消息传递)

    1. **WM_COPYDATA** 消息:这是最简单且常见的进程间通信方式之一。一个进程可以发送`WM_COPYDATA`消息到另一个进程,携带不超过64KB的数据。在MFC中,可以使用`CWnd::SendMessage`或`CWnd::PostMessage`函数发送`WM...

    进程 调度、创建、查看、通信

    举个例子,创建一个简单的管道通信的C程序,可以使用`pipe()`函数创建管道,`dup2()`重定向标准输入输出,`fork()`创建子进程,然后父子进程可以通过管道互相传递数据。 总结来说,理解和掌握C语言中关于进程的操作...

    深刻理解Linux进程间通信.pdf

    首先,管道(Pipe)是一种最基本的IPC方法,它允许一个进程和另一个进程之间进行单向数据流通信。管道分为匿名管道和有名管道(FIFO)。匿名管道使用起来较为简单,但由于其没有名字,只能在具有亲缘关系的进程间...

    linux进程间通信

    1. **管道(Pipe)**:管道是最简单的IPC形式,它提供一个单向的数据流,可以将数据从一个进程传递到另一个进程。管道分为无名管道和命名管道(FIFO)。无名管道仅适用于具有亲缘关系的进程,如父子进程之间;命名...

    进程间的通信

    - 实现:通过`pipe()`函数创建管道,利用`fork()`函数创建子进程,然后分别使用`write()`和`read()`进行数据交换。 2. **消息队列(Message Queue)**: - 简介:消息队列允许进程之间发送消息,而无需知道接收者是...

    最简单的进程间通讯的例子:delphi编程实例

    在Delphi编程环境中,我们可以利用多种方法实现IPC,本实例将探讨一个简单的方法。 首先,我们要了解Delphi中的几个基本概念。Delphi是一个基于Object Pascal的集成开发环境,它提供了丰富的API和组件库来支持进程...

    实验七-进程通信.doc

    **管道(pipe)**是一种最基本的进程间通信(IPC)机制,允许两个进程之间通过共享内存区域进行数据交换。管道支持半双工操作模式,即数据只能在一个方向上传输。一般情况下,读取管道的一方会关闭管道的写入端,而写入...

    进程通信.doc

    1. **管道(pipe)和有名管道(FIFO)**:管道是一种最简单的进程间通信方式,用于连接一个进程的输出和另一个进程的输入,实现单向的数据流动。有名管道(FIFO)则可以在文件系统中持久化,允许非相关进程间通信。 ...

Global site tag (gtag.js) - Google Analytics