Отказано в разрешении на запуск tcp-сервера через порт 80 через сеть 3g с использованием Eneter Messaging и протокольных буферов - PullRequest
0 голосов
/ 15 октября 2018

Я работаю над проектом, в котором мое приложение для Android должно работать как сервер для других клиентов Android. Я использую Среду обмена сообщениями Eneter , которая использует Sockets и Google Protobuf .. На Wi-Fi все работаеткак очарование, но как только я переключаюсь на 3g сеть (попробуйте запустить сервер, используя 3g общедоступный IP-адрес телефона и порт 80/81), я получаю следующую ошибку: EACCES (В доступе отказано)

E/EneterMessaging: ~24216 eneter.messaging.messagingsystems.tcpmessagingsystem.internal.TcpListenerProvider.startListening TcpListenerProvider  failed to start listening.
                   Exception:
                   java.net.BindException: bind failed: EACCES (Permission denied)
                   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) 

У меня есть этиразрешения в моем манифесте:

<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"/>

и это код, который запускает сервер:

public void StartServer() throws Exception
    {
        // Create sender sending MyRequest and as a response receiving MyResponse
        // Instantiate Protocol Buffer based serializer.
        ISerializer aSerializer = new ProtoBufSerializer();

        // Create sender sending MyRequest and as a response receiving MyResponse
        // The sender will use Protocol Buffers to serialize/deserialize messages.
        IDuplexTypedMessagesFactory aRecieverFactory = new DuplexTypedMessagesFactory(aSerializer);
        myReceiver = aRecieverFactory.createDuplexTypedMessageReceiver(MessageDeclarations.MyMsg.class, MessageDeclarations.MyMsg.class);
        myReceiver.messageReceived().subscribe(myOnRequestHandler);

        if(aMessaging == null)aMessaging = new TcpMessagingSystemFactory();

        IDuplexInputChannel anInputChannel
                = aMessaging.createDuplexInputChannel(Service_URL);//Service_URL = "tcp://xxx.xxx.x.xx:80/ with public ip adress


        // Attach the output channel to the sender and be able to send
        // messages and receive responses.
        myReceiver.attachDuplexInputChannel(anInputChannel);

        isConnected = true;
        showNotification("Server Started","url: "+Service_URL,Color.GREEN);
    }

Исключение происходит на

myReceiver.attachDuplexInputChannel(anInputChannel);

То, где запускается Eneterсервер сокетов.

РЕДАКТИРОВАТЬ: С this Я обнаружил, что для привязки к портам <1024 вам нужны привилегии root. </strong> Поэтому я попробовал порты, такие как 1025,8080, 8081, теперь я получаю это исключение: Невозможно назначить запрошенный адрес , я не могу использовать общедоступный IP-адрес сети 3G для запуска сервера сокетов или я что-то упустил?

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)

Буду признателен за вашу помощь.

Пожалуйста

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

ОБНОВЛЕНИЕ: Я исправил это

Спасибо greeble31 за ваши разъяснения, эта ссылка была полезна.

После переключения с Wi-Fi на 3G оператор сети назначает телефону частный IP-адрес 10.xx.xx.xx, который позднее преобразуется NAT в общий публичный IP-адрес.

Если все узлы (телефоны пытаютсядостичь друг друга) находятся на одном провайдере и - (не уверен насчет эффективности этого) - относительно близко, как в моем случае, с использованием назначенного адреса провайдера (в моем случае 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;
    }

Однако я должен проверить его на разных носителях и в разных местах, чтобы убедиться, что телефон не использует одну и ту же антенну 3G.Я отредактирую это так, как получу результаты.

Спасибо.

0 голосов
/ 16 октября 2018

Ответ на оригинальный вопрос

Назначение порта не выполняется, поскольку, как вы заметили, 80 является привилегированным портом.

Ответ на обновленный вопрос

Не удалось назначить IP-адрес, поскольку, как оказалось, в вашем коде был неверный IP-адрес.После того, как вы отключили свою WiFi-сеть (предположительно), чтобы войти в мобильную сеть, используемый вами адрес был удален из системы, и ваш оператор беспроводной связи назначил вам другой адрес.Использование 0.0.0.0, по сути, говорит вашей серверной библиотеке: «Я хочу слушать все интерфейсы».(Другой вариант - выяснить ваш мобильный IP-адрес и использовать его вместо этого.) Но это подводит нас к последней проблеме:

Комментарий к вашей текущей проблеме

Может быть много причин, почему он не соединяется.Я подозреваю, что это, вероятно, NAT , как описано в этот вопрос .Короче говоря, очень мало приложений (если есть), использующих выбранную вами архитектуру (запуск сервера на телефоне абонента, подключенного к мобильной сети).Из-за NAT телефонам почти всегда приходится «набирать номер», чтобы сформировать соединение (в мобильной сети).И ваш сервер не набирает номер;он слушает.

Эти ограничения не будут применяться к вашей локальной сети WiFi, если вы не пересекаете границу NAT.

Чтобы решить эту проблему, вам, вероятно, потребуетсязнать архитектуру сети и некоторое обучение по отладке сети.Инструменты захвата, такие как Wireshark, очень помогают.

Если вам нужна дополнительная помощь по этому вопросу, и ни один из других ответов по SO не поможет вам, вероятно, лучше начать новый вопрос.

...