Android - ***service DatagramChannel.open() 不工作
Posted
技术标签:
【中文标题】Android - ***service DatagramChannel.open() 不工作【英文标题】:Android - ***service DatagramChannel.open() not working 【发布时间】:2017-12-05 21:00:09 【问题描述】:我想创建重新路由数据包的应用程序。我使用 ***service(因为不需要 root 电话),使用 toy*** 和这段代码 http://www.thegeekstuff.com/2014/06/android-***-service/ 但问题出在这一行 DatagramChannel tunnel = DatagramChannel.open(); 这一行抛出异常。 这是我的代码
公共类 My***Service 扩展 ***Service 公共静态字符串连接=“启动服务”; 公共静态字符串 DISCONNECTION = "StopService"; 公共静态布尔工作=假; 私有线程 mThread; 私有 ParcelFileDescriptor mInterface; 建造者建造者=新建造者(); // 服务接口 @覆盖 public int onStartCommand(Intent intent, int flags, int startId) // 通过创建一个新线程来启动一个新会话。 if (intent != null && DISCONNECTION.equals(intent.getAction())) 工作=假; 停止前景(真); mThread.interrupt(); 停止自我(); 返回 START_NOT_STICKY; 工作=真; mThread = 新线程(新可运行() @覆盖 公共无效运行() 尝试 Log.d("***服务", "0"); mInterface = builder.setSession("My***Service") .addAddress("192.168.1.3", 24) .addDnsServer("8.8.8.8") .addRoute("0.0.0.0", 0).建立(); FileInputStream in = new FileInputStream( mInterface.getFileDescriptor()); 文件输出流输出 = 新文件输出流( mInterface.getFileDescriptor()); Log.d("***service", "1" + (mInterface != null)); DatagramChannel 隧道 = DatagramChannel.open(); Log.d("***service", "2" + (tunnel != null)); Log.d("***service", "3" + tunnel.connect(new InetSocketAddress("127.0.0.1", 8087))); //tunnel.connect(new InetSocketAddress("127.0.0.1", 8087)); 隧道.configureBlocking(假); 保护(隧道。socket()); //e。使用循环传递数据包。 ByteBuffer 数据包 = ByteBuffer.allocate(Short.MAX_VALUE); Log.d("***服务", "4"); 而(!Thread.interrupted()) Log.d("***服务", "5"); int 长度 = in.read(packet.array()); 如果(长度> 0) 数据包.限制(长度); 隧道。写(数据包); // 可能有更多的传出数据包。 Log.d("***服务", "6"); Log.d("***服务", "7"); 长度=隧道。读取(数据包); Log.d("***服务", "8"); 如果(长度> 0) 如果 (packet.get(0) != 0) out.write(packet.array(), 0, 长度); Log.d("***服务", "9"); 数据包.clear(); Log.d("***服务", "10"); 线程.sleep(100); Log.d("***服务", "11"); 捕捉(异常 e) e.printStackTrace(); 最后 尝试 if (mInterface != null) mInterface.close(); 米接口=空; 捕捉(异常 e) , "My***Runnable"); //启动服务 mThread.start(); 返回 START_STICKY; @覆盖 公共无效 onDestroy() // TODO 自动生成的方法存根 如果(mThread!= null) mThread.interrupt(); super.onDestroy();
这是日志:
07-02 15:13:09.271 8853-8853/app.my.my***service D/ActivityThread: SVC-Calling onStartCommand: app.my.my***service.My***Service@424f59f0, flags=0, startId=1
07-02 15:13:09.272 8853-8853/app.my.my***service D/dalvikvm: create interp thread : stack size=128KB
07-02 15:13:09.272 8853-8853/app.my.my***service D/dalvikvm: create new thread
07-02 15:13:09.274 8853-8853/app.my.my***service D/dalvikvm: new thread created
07-02 15:13:09.274 8853-8853/app.my.my***service D/dalvikvm: update thread list
07-02 15:13:09.274 8853-9304/app.my.my***service D/dalvikvm: threadid=11: interp stack at 0x7d83d000
07-02 15:13:09.274 8853-9304/app.my.my***service D/dalvikvm: threadid=11: created from interp
07-02 15:13:09.274 8853-8853/app.my.my***service D/dalvikvm: start new thread
07-02 15:13:09.274 8853-9304/app.my.my***service D/dalvikvm: threadid=11: notify debugger
07-02 15:13:09.274 8853-9304/app.my.my***service D/dalvikvm: threadid=11 (My***Runnable): calling run()
07-02 15:13:09.275 8853-8853/app.my.my***service D/ActivityThread: SVC-SERVICE_ARGS handled : 0 / ServiceArgsDatatoken=android.os.BinderProxy@424ef338 startId=1 args=Intent act=StartService cmp=app.my.my***service/.My***Service
07-02 15:13:09.275 8853-9304/app.my.my***service D/***service: 0
07-02 15:13:09.306 8853-8853/app.my.my***service D/ActivityThread: SVC-BIND_SERVICE handled : 0 / BindServiceDatatoken=android.os.BinderProxy@424ef338 intent=Intent act=android.net.***Service cmp=app.my.my***service/.My***Service
07-02 15:13:09.447 8853-9304/app.my.my***service D/***service: 1 true
07-02 15:13:09.471 8853-9304/app.my.my***service W/System.err: java.net.SocketException: socket failed: EACCES (Permission denied)
07-02 15:13:09.481 8853-9304/app.my.my***service W/System.err: at libcore.io.IoBridge.socket(IoBridge.java:622)
07-02 15:13:09.481 8853-9304/app.my.my***service W/System.err: at java.nio.DatagramChannelImpl.<init>(DatagramChannelImpl.java:75)
07-02 15:13:09.481 8853-9304/app.my.my***service W/System.err: at java.nio.SelectorProviderImpl.openDatagramChannel(SelectorProviderImpl.java:33)
07-02 15:13:09.481 8853-9304/app.my.my***service W/System.err: at java.nio.channels.DatagramChannel.open(DatagramChannel.java:66)
07-02 15:13:09.481 8853-9304/app.my.my***service W/System.err: at app.my.my***service.My***Service$1.run(My***Service.java:50)
07-02 15:13:09.482 8853-9304/app.my.my***service W/System.err: at java.lang.Thread.run(Thread.java:848)
07-02 15:13:09.482 8853-9304/app.my.my***service W/System.err: Caused by: libcore.io.ErrnoException: socket failed: EACCES (Permission denied)
07-02 15:13:09.482 8853-9304/app.my.my***service W/System.err: at libcore.io.Posix.socket(Native Method)
07-02 15:13:09.482 8853-9304/app.my.my***service W/System.err: at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:181)
07-02 15:13:09.482 8853-9304/app.my.my***service W/System.err: at libcore.io.IoBridge.socket(IoBridge.java:607)
07-02 15:13:09.482 8853-9304/app.my.my***service W/System.err: ... 5 more
07-02 15:13:09.536 8853-9304/app.my.my***service D/dalvikvm: threadid=11: exiting
07-02 15:13:09.536 8853-9304/app.my.my***service D/dalvikvm: threadid=11: bye!
07-02 15:13:09.583 8853-8853/app.my.my***service D/ActivityThread: SVC-UNBIND_SERVICE handled : 0 / BindServiceDatatoken=android.os.BinderProxy@424ef338 intent=Intent act=android.net.***Service cmp=app.my.my***service/.My***Service
我还有一个问题。我是否必须为此使用 *** 服务器,或者我可以在不使用此服务的情况下以默认方式(隧道)返回数据包?
【问题讨论】:
【参考方案1】:这个问题已经很老了,但是......
你的堆栈跟踪有这一行:
SocketException:套接字失败:EACCES(权限被拒绝)
这似乎是一个权限问题。您可以通过将 INTERNET 权限添加到您的 AndroidManifest.xml 来解决它(如果您已经拥有此权限并且仍然遇到此异常,只需添加ACCESS 权限是这样的):
<manifest
..... >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
....
【讨论】:
【参考方案2】:已经为您的 AndroidManifest .xml 文件设置了权限?喜欢这个:
<service
android:name=".My***Service"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_***_SERVICE">
<intent-filter>
<action android:name="android.net.***Service"/>
</intent-filter>
</service>
【讨论】:
以上是关于Android - ***service DatagramChannel.open() 不工作的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft.Data.Services.Client.dll 与 System.Data.Services.Client.dll