【问题标题】:Allowing user to stablish IP address using oscP5 with Processing Android允许用户使用 oscP5 和 Processing Android 来稳定 IP 地址
【发布时间】:2013-09-13 23:57:38
【问题描述】:

您好,处理开发人员,

我正在使用 OSCP5 链接两个处理草图,一个来自 android 设备,另一个在我的计算机中,通过 WiFi。

我已经尝试过直接在 setup() 上的新网络地址上键入我的计算机的 IP 地址,它工作得很好。但是,我认为最好让用户有机会将计算机的 IP 地址更改为发送消息的位置(可能会更改 IP 或更改网络,然后 android 应用程序将无法运行)。

我正在使用一个文本字段让用户输入 IP 地址,然后在一个名为 ipAddress 的字符串中使用它,该字符串进入进入 myRemoteLocation 的 NetAddress。

这是我的代码(电话上有):

import oscP5.*;
import netP5.*;

import apwidgets.*;

OscP5 oscP5;
NetAddress myRemoteLocation;

PWidgetContainer widgetContainer;
PEditText textField;
PButton button1;

PImage fondo;

boolean ValidIP = false;
String ipAddress = "192.168.0.107";

void setup() {
  size(480,800);
  smooth();

  fondo = loadImage("fondoAnd.jpg");

  widgetContainer = new PWidgetContainer(this);
  textField = new PEditText(10,40,380,120);
  button1 = new PButton(10,190,200,100,"Conectar");
  widgetContainer.addWidget(textField);
  widgetContainer.addWidget(button1);

  oscP5 = new OscP5(this,12000);
  myRemoteLocation = new NetAddress(ipAddress,12000);
}

void draw() {
  if (ValidIP == true){ 
    widgetContainer.hide();
    myRemoteLocation = new NetAddress(ipAddress,12000);
    background(fondo);
  }
  else if (ValidIP == false){
    background(0);
    textSize(20);
    text("Ingrese un IP válido",10,30);
    widgetContainer.show();
  }
}

void mousePressed(){
    OscMessage myMessage = new OscMessage("/test");
    myMessage.add(8);
    oscP5.send(myMessage, myRemoteLocation);
    println("enviomensaje"); //I print this in the console to know if it sends a message
}

void onClickWidget(PWidget widget){
  if(widget == button1){
    ipAddress = textField.getText();
    myRemoteLocation = new NetAddress(ipAddress,12000);
    ValidIP = true;
  }
}

【问题讨论】:

    标签: android ip processing


    【解决方案1】:

    我已将 OSCP5 用于a project,将许多 Android 设备用作 OSC 客户端,并将计算机用作 OSC 服务器。我建议从broadcast sample 开始。请注意,服务器会在端口 32000 上侦听来自任何 ip 的“/server/connect”消息。这样您就不需要将 android 设备的 ip 硬编码到服务器中,但在这个阶段您仍然需要硬编码服务器进入客户端 android 设备。

    我绕过这个限制的方法是将“/server/connect”消息发送给每个愿意收听的人(“255.255.255.255”)。一旦服务器连接了一个ip,它就会向客户端发送一条消息。然后客户端将从该消息中获取 IP 地址,因此它不需要将所有后续消息发送到“255.255.255.255”。

    我在 android 设备上使用了 android SDK,在计算机上使用了 Processing,所以我的语法看起来会有所不同,但你应该能够理解 OSC 部分。这是一个简化的版本:

    package com.hirschandmann.updclient.network;
    
    import netP5.NetAddress;
    import oscP5.OscArgument;
    import oscP5.OscEventListener;
    import oscP5.OscMessage;
    import oscP5.OscP5;
    import oscP5.OscStatus;
    import android.util.Log;
    
    public class NetMan implements OscEventListener {
    
        public static final int PORT_IN = 12000;
        public static final int PORT_OUT = 32000;
        public static NetAddress SERVER;
        public static NetAddress EVERYTHING = new NetAddress("255.255.255.255",PORT_OUT);
    
        private static final String TAG = "NetMan";
        private OscP5 osc;
    
        public NetMan(){
            osc = new OscP5(this, PORT_IN);
        }
        public void oscEvent(OscMessage m) {
            String pattern = m.addrPattern();
            if(SERVER == null) {
                SERVER = new NetAddress(m.address().replace("/", ""), PORT_OUT);
                System.out.println(SERVER);
            }
        }
        public void connect(){
            Log.d("NetMan","connect");
            new ConnectTask().execute();
        }
        public void disconnect(){
            new DisconnectTask().execute();
        }
        @Override
        public void oscStatus(OscStatus status) {
            System.out.println(status);
        }
    }
    

    和 ConnectTask:

    package com.hirschandmann.udpclient.network;
    
    import netP5.NetAddress;
    import oscP5.OscMessage;
    import oscP5.OscP5;
    import android.os.AsyncTask;
    
    public class ConnectTask extends AsyncTask<Void, Void, Void> {
    
        @Override
        protected Void doInBackground(Void... params) {
            System.out.println("sending connect message: " + NetMan.PORT_OUT);
            OscMessage m = new OscMessage("/server/connect",new Object[0]);
            try{
                OscP5.flush(m,NetMan.SERVER != null ? NetMan.SERVER : NetMan.EVERYTHING);
            }catch(NullPointerException e) {
                System.err.println(e.getMessage());
            }
            if(NetMan.SERVER != null) System.out.println("NetMan.SERVER: " + NetMan.SERVER);
            return null;
        }
    
    }
    

    所以你应该试试电脑上的广播样本和类似的东西:

    import netP5.*;
    
    import apwidgets.*;
    
    OscP5 oscP5;
    NetAddress myRemoteLocation;
    
    PWidgetContainer widgetContainer;
    PEditText textField;
    PButton button1;
    
    PImage fondo;
    
    boolean ValidIP = false;
    String ipAddress = "255.255.255.255";
    
    void setup() {
      size(480,800);
      smooth();
    
      fondo = loadImage("fondoAnd.jpg");
    
      widgetContainer = new PWidgetContainer(this);
      textField = new PEditText(10,40,380,120);
      button1 = new PButton(10,190,200,100,"Conectar");
      widgetContainer.addWidget(textField);
      widgetContainer.addWidget(button1);
    
      oscP5 = new OscP5(this,12000);
      myRemoteLocation = new NetAddress(ipAddress,12000);
    }
    
    void draw() {
      if (ValidIP == true){ 
        widgetContainer.hide();
        myRemoteLocation = new NetAddress(ipAddress,12000);
        background(fondo);
      }
      else if (ValidIP == false){
        background(0);
        textSize(20);
        text("Ingrese un IP válido",10,30);
        widgetContainer.show();
      }
    }
    
    void mousePressed(){
        OscMessage myMessage = new OscMessage("/server/connect");
        myMessage.add(8);
        oscP5.send(myMessage, myRemoteLocation);
        println("enviomensaje"); //I print this in the console to know if it sends a message
    }
    
    void onClickWidget(PWidget widget){
      if(widget == button1){
        ipAddress = textField.getText();
        myRemoteLocation = new NetAddress(ipAddress,12000);
        ValidIP = true;
      }
    }
    void oscEvent(OscMessage m) {
      String pattern = m.addrPattern();
      if(ipAddress.equals("255.255.255.255")) {
        ipAddress = m.address().replace("/", "");
        System.out.println("server is at: " + ipAddress);
      }
    }
    

    以上代码未经测试,但应该有所帮助。

    请注意,我在 UDP 模式下使用了 OSC。还有一种 TCP 模式。 使用 UDP,您可以广播到多个 ip,但不能保证您的消息 将跨越,每条消息限制为最多 64K 的数据。 因为 UDP 数据包没有确认,所以它比 TCP 稍快。 使用 TCP,可以保证所有数据包都到达另一端,但需要加快速度 以及缺乏转播能力。您还可以发送超过 64K 的数据。 在我的应用程序中,我必须发送 9MP 和 12MP 图像,所以我同时使用了 UDP 和 TCP:

    • UDP 获取服务器地址并发送快速消息 最少的数据
    • TCP 传输文件:打开一个 tcp 套接字来发送数据并在传输完成时关闭它。

    我遇到的另一个问题是 Android 上的 wifi 速度。 Wifi 在 Android 设备上的处理方式与在计算机上的处理方式不同。操作系统正在尝试尽可能地节省电池电量,但这也意味着如果您的设备上几乎没有活动,Wifi 将进入低延迟模式:它可以节省电池电量,但连接速度非常慢,所以如果您需要通过 OSC 快速响应这是一个问题。我haven't found a proper solution 解决了除了锁定 wifi 和电源始终开启之外的问题:用电池寿命换取一点 Wifi 响应能力。我希望我知道solution to this problem。如果您有任何建议,请分享。

    HTH

    【讨论】:

    • 非常感谢!还没有测试,但我会让你知道它是否有效。 :D
    • 酷,您可以随意勾选/标记。此外,您可能想查看 avahi 或类似工具,这些工具可能允许您通过名称而不是 ip 访问您的联网设备
    猜你喜欢
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 2016-07-23
    • 2017-05-13
    • 2020-05-09
    • 2015-12-28
    相关资源
    最近更新 更多