Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用eNet消息和协议缓冲区通过3g网络在端口80上启动tcp服务器的权限被拒绝_Java_Android_Sockets_Tcp_Protocol Buffers - Fatal编程技术网

Java 使用eNet消息和协议缓冲区通过3g网络在端口80上启动tcp服务器的权限被拒绝

Java 使用eNet消息和协议缓冲区通过3g网络在端口80上启动tcp服务器的权限被拒绝,java,android,sockets,tcp,protocol-buffers,Java,Android,Sockets,Tcp,Protocol Buffers,我正在做一个项目,我的android应用程序应该作为其他android客户端的服务器。。我用的是Sockets和googleprotobuf。。在wifi上,一切都很有魅力,但一旦我切换到3g网络(尝试使用手机的3g公共ip地址和端口80/81启动服务器),我就会出现以下错误:EACCES(权限被拒绝) 我在清单中拥有以下权限: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

我正在做一个项目,我的android应用程序应该作为其他android客户端的服务器。。我用的是Sockets和googleprotobuf。。在wifi上,一切都很有魅力,但一旦我切换到3g网络(尝试使用手机的3g公共ip地址和端口80/81启动服务器),我就会出现以下错误:EACCES(权限被拒绝)

我在清单中拥有以下权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET"/>
异常发生在

myReceiver.attachDuplexInputChannel(anInputChannel);
这就是eNet启动套接字服务器的地方

EDIT:From我发现绑定<1024个端口需要根权限。所以我尝试了1025、8080、8081等端口,现在我得到了 改为此异常:无法分配请求的地址,是吗 我不能使用3G网络公共ip地址启动套接字服务器 还是我遗漏了什么

我将感谢你的帮助


请回答原问题

端口分配失败,因为正如您所指出的,80是一个特权端口

更新问题的答案

IP地址分配失败,因为您的代码中有错误的IP地址。一旦您关闭WiFi网络(大概)进入移动网络,您使用的地址将从系统中删除,您的无线运营商将为您分配一个不同的地址。使用0.0.0.0基本上会告诉您的服务器库,“我想监听所有接口”。(另一个选择是计算出您的移动IP地址,并使用该地址。)但这就引出了最后一个问题:

对当前问题的评论

可能有很多原因导致它无法连接。我怀疑这可能是,如中所述。长话短说,很少有应用程序(如果有的话)使用您选择的架构(在连接到移动网络的订户手机上运行服务器)。由于NAT,手机几乎总是必须“拨出”才能形成连接(在移动网络上)。而且你的服务器没有拨出;它在听

这些限制不适用于您的本地WiFi网络,只要您不跨越NAT边界

要解决这个问题,您可能需要了解网络体系结构,并接受一些网络调试方面的培训。像Wireshark这样的捕获工具帮了大忙


如果你在这方面需要更多帮助,而其他答案对你没有帮助,那么最好开始一个新问题。

更新:我解决了它。

感谢greeble31的澄清,这是 有用

从wifi切换到3G后,网络运营商将为手机分配一个专用IP地址10.xx.xx.xx,该地址随后由NAT转换为共享公共IP地址

如果所有节点(试图互相联系的电话)都在同一个ISP上,并且(不确定这一个的有效性)与我的情况相对较近,使用分配的ISP地址(在我的情况下是10.xx.xx.xx)而不是公共IP地址应该可以做到这一点

我用它来获取工作IP地址:

public String getAndroidIP() {
        try {
            String interfaces = "";
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf
                        .getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()
                            && inetAddress instanceof Inet4Address) {

                        interfaces = interfaces
                                + inetAddress.getHostAddress().toString();
                        Log.d("interface NET",interfaces);
                    }
                    Log.d("interface Adress",inetAddress.getHostAddress().toString());
                }
            }
            return (interfaces);
        } catch (SocketException ex) {
            Log.d("getAndroidIP", ex.toString());
        }
        return null;
    }
公共字符串getAndroidp(){
试一试{
字符串接口=”;
对于(枚举en=网络接口
.getNetworkInterfaces();en.hasMoreElements();){
NetworkInterface intf=en.nextElement();
对于(枚举枚举enumIpAddr=intf
.getInetAddresses();EnumipAddress.hasMoreElements();){
InetAddress InetAddress=enumIpAddr.nextElement();
如果(!inetAddress.isLoopbackAddress()
&&inetAddress实例(Inet4Address的实例){
接口=接口
+inetAddress.getHostAddress().toString();
Log.d(“接口网”,接口);
}
Log.d(“接口地址”,inetAddress.getHostAddress().toString());
}
}
返回(接口);
}捕获(SocketException例外){
Log.d(“getAndroidp”,例如toString());
}
返回null;
}
但是,我应该在不同的载体和不同的环境下测试它 确保手机不共享同一3G天线的位置。我将 当我得到结果时,用它们编辑这个


谢谢。

是的,尝试在
服务URL
中使用0.0.0.0作为ip地址。使用0.0.0.0修复错误并启动服务器,但是我无法使用服务器电话的公共ip地址通过3G/4G网络从客户端连接到它,我得到以下信息:
java.net.SocketTimeoutException:无法连接到/xx.xx.xx.xx.xx30000ms后的(端口8080)
。xx.xx.xx.xx是手机的公共IP
myReceiver.attachDuplexInputChannel(anInputChannel);
E/EneterMessaging: ~25710 eneter.messaging.messagingsystems.simplemessagingsystembase.internal.DefaultDuplexInputChannel.startListening DefaultDuplexInputChannel 'tcp://105.66.131.38:8080/'  failed to start listening.
                   Exception:
                   java.net.BindException: bind failed: EADDRNOTAVAIL (Cannot assign requested address)
                   libcore.io.IoBridge.bind(IoBridge.java:99)
                   java.net.PlainSocketImpl.bind(PlainSocketImpl.java:132)
                   java.net.ServerSocket.bind(ServerSocket.java:335)
                   eneter.messaging.messagingsystems.tcpmessagingsystem.NoneSecurityServerFactory.createServerSocket(NoneSecurityServerFactory.java:51)
                   eneter.messaging.messagingsystems.tcpmessagingsystem.internal.TcpListenerProvider.startListening(TcpListenerProvider.java:123)
                   eneter.messaging.messagingsystems.tcpmessagingsystem.TcpInputConnector.startListening(TcpInputConnector.java:134)
                   eneter.messaging.messagingsystems.simplemessagingsystembase.internal.DefaultDuplexInputChannel.startListening(DefaultDuplexInputChannel.java:96)
                   eneter.messaging.infrastructure.attachable.internal.AttachableDuplexInputChannelBase.attachDuplexInputChannel(AttachableDuplexInputChannelBase.java:40)
                   com.inactivity.magamine.teatime.services.TCPService.StartServer(TCPService.java:261)
                   com.inactivity.magamine.teatime.services.TCPService$6.run(TCPService.java:279)
                   java.lang.Thread.run(Thread.java:818)
public String getAndroidIP() {
        try {
            String interfaces = "";
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf
                        .getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()
                            && inetAddress instanceof Inet4Address) {

                        interfaces = interfaces
                                + inetAddress.getHostAddress().toString();
                        Log.d("interface NET",interfaces);
                    }
                    Log.d("interface Adress",inetAddress.getHostAddress().toString());
                }
            }
            return (interfaces);
        } catch (SocketException ex) {
            Log.d("getAndroidIP", ex.toString());
        }
        return null;
    }