Android к Unity - проблема подключения tcp - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь установить sh соединение между приложением Android (созданным в Android Studio) и приложением Unity (P C) для отправки-получения сообщений (строковые переменные) в качестве одноранговых to-peer (может быть как сервером, так и клиентом)

  • При попытке подключиться к локальному IP-адресу Android - я получаю:
    System.Net.Sockets.SocketException (0x80004005): The requested address is not valid in its context.
      at System.Net.Sockets.Socket.Bind (System.Net.EndPoint localEP) [0x00043] in <ae22a4e8f83c41d69684ae7f557133d9>:0 
      at MyNetworkClass.networkCode () [0x0003a] in D:\Stuff\Unity\Soft_games\Droid_AI\New Unity Project\Assets\Scripts\MyNetworkClass.cs:115 
    UnityEngine.Debug:Log(Object)
    MyNetworkClass:networkCode() (at Assets/Scripts/MyNetworkClass.cs:170)
    System.Threading.ThreadHelper:ThreadStart()
  • При попытке подключиться к 2 приложениям P C (для проверки соединения) - я получаю "
System.Net.Sockets.SocketException (0x80004005): Only one usage of each socket address (protocol/network address/port) is normally permitted.

  at System.Net.Sockets.Socket.Bind (System.Net.EndPoint localEP) [0x00043] in <ae22a4e8f83c41d69684ae7f557133d9>:0 
  at MyNetworkClass.networkCode () [0x0003a] in D:\Stuff\Unity\Soft_games\Droid_AI\New Unity Project\Assets\Scripts\MyNetworkClass.cs:115 
UnityEngine.Debug:Log(Object)
MyNetworkClass:networkCode() (at Assets/Scripts/MyNetworkClass.cs:170)
System.Threading.ThreadHelper:ThreadStart()

Вот используемые сценарии: Unity (P C)

using UnityEngine;
using System;
using System.Collections;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Collections.Generic;
using System.Text;

public class MyNetworkClass : MonoBehaviour
{
    public NetworkStream receiveStream;

    System.Threading.Thread SocketThread;
    volatile bool keepReading = false;

    // Use this for initialization
    void Start()
    {
        Application.runInBackground = true;
        startServer();
    }

    public void Reconnect()
    {
        stopServer();
        startServer();
    }

    public void SendMes()
    {
        if (listener != null && keepReading && receiveStream != null)// && listener.Connected)
        {
            if (receiveStream.CanWrite)
            {
                //listener.Accept();
                byte[] sendM = Encoding.Default.GetBytes(VarsStatic.m_Input.text);
                receiveStream.Write(sendM, 0, sendM.Length);
            }
        }
    }

    void startServer()
    {
        SocketThread = new System.Threading.Thread(networkCode);
        SocketThread.IsBackground = true;
        SocketThread.Start();
    }

    private string getIPAddress()
    {
        IPHostEntry host;
        string localIP = "";
        host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress ip in host.AddressList)
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                localIP = ip.ToString();
            }

        }
        return localIP;
    }


    Socket listener;
    Socket handler;

    void networkCode()
    {
        string data;

        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // host running the application.
        IPAddress myIp = IPAddress.Parse("192.168.0.104");
        int port = 9700;
        IPEndPoint localEndPoint = new IPEndPoint(myIp, port);

        // Create a TCP/IP socket. 
        listener = new Socket(myIp.AddressFamily,
            SocketType.Stream, ProtocolType.Tcp);

        // Bind the socket to the local endpoint and 
        // listen for incoming connections.

        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(10);


            Debug.Log("IP: " + localEndPoint.Address.ToString() + " | " + myIp.ToString() + " -- Port: " + localEndPoint.Port.ToString() + " | " + VarsStatic.Port);
            // Start listening for connections.
            while (true)
            {
                keepReading = true;

                // Program is suspended while waiting for an incoming connection.
                Debug.Log("Waiting for Connection");     //It works

                handler = listener.Accept();
                Debug.Log("Client Connected");     //It doesn't work
                receiveStream = new NetworkStream(handler);
                data = null;

                // An incoming connection needs to be processed.
                while (keepReading)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    Debug.Log("Received from Server");

                    if (bytesRec <= 0)
                    {
                        keepReading = false;
                        handler.Disconnect(true);
                        break;
                    }

                    data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
                    if (data.IndexOf("<EOF>") > -1)
                    {
                        break;
                    }
                    //
                    string Test = Encoding.UTF8.GetString(bytes);
                    Debug.Log(Test);

                    System.Threading.Thread.Sleep(1);
                }

                System.Threading.Thread.Sleep(1);
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }

    void stopServer()
    {
        keepReading = false;
        receiveStream = null;

        //stop thread
        if (SocketThread != null)
        {
            SocketThread.Abort();
        }

        if (handler != null && handler.Connected)
        {
            handler.Disconnect(false);
            Debug.Log("Disconnected!");
        }
    }

    void OnDisable()
    {
        stopServer();
    }

}

Android

 class MyServer implements Runnable {
        ServerSocket ss;
        Socket m_s;
        DataInputStream dis;
        String message;
        Handler handler = new Handler();

        // MAIN EVERYFRAME UPDATE (Inet handle's base)
        @Override
        public void run() {
            // Server
            try {
                ss = new ServerSocket(m_Port);
                while (true) {
                    m_s = ss.accept();
/*                    handler.post(new Runnable() { // Message - Sending Message
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"Waiting for client", Toast.LENGTH_SHORT).show();
                        }
                    })  ;*/
                    dis = new DataInputStream(m_s.getInputStream());
                    message = dis.readUTF();

                    handler.post(new Runnable() {
                        @Override
                        public void run() {

                            boolean messageOn = false;
                            // Message Extra Process
                            if (message.equals("Open Camera")) {
                                messageOn = true;
                                Toast.makeText(getApplicationContext(), "Opening Camera on another client", Toast.LENGTH_SHORT).show();
                            } else if (message.equals("Open Gallery")) {
                                messageOn = true;
                                Toast.makeText(getApplicationContext(), "Opening Gallery on another client", Toast.LENGTH_SHORT).show();
                            }
                            //

                            if (!messageOn)
                                Toast.makeText(getApplicationContext(), "Message received from client: " + message, Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
                // report errors and keep listening.
//                Debug.Log("Network Error: " + e.Message);

                // Sleep 5 seconds so that we don't flood the output with errors
                try {
                    Thread.sleep(SleepTime);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }

        }
    }

    class BackgroundTask extends AsyncTask<String, Void, String> {
        Socket s;
        DataOutputStream dos;
        String ip, message;

        @Override
        protected String doInBackground(String... strings) {
            ip = strings[0];
            message = strings[1];

            try {
                s = new Socket(ip, m_Port);
                dos = new DataOutputStream(s.getOutputStream());
                dos.writeUTF(message);

                dos.close();
                s.close();
            } catch (IOException e) { // UnknownHostException
                e.printStackTrace();
            }

            return null;
        }
    }

Примечание: - все используют один и тот же порт.

ps Android код проверен и работает между другими экземплярами одного и того же приложения (gradle) эмулятор - встроенный в телефон apk)

Заранее спасибо, Ray

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...