Android 到 Unity – TCP 连接问题

huangapple 未分类评论47阅读模式
英文:

Android to Unity - tcp connection problem

问题

以下是您提供的内容的翻译:

我正在尝试在 Android 应用(在 Android Studio 中制作)和 Unity(PC)应用之间建立连接,以便以对等方式发送和接收消息(字符串变量),可以是对等的服务器或客户端。

  • 在尝试连接到 Android 的本地 IP 时,我收到以下错误:
    System.Net.Sockets.SocketException (0x80004005): 请求的地址在其上下文中无效。
      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 个 PC 应用程序(以测试连接)时,我收到以下错误:
System.Net.Sockets.SocketException (0x80004005): 通常情况下只允许使用每个套接字地址(协议/网络地址/端口)一次。

  at System.Net.Sockets.Socket.Bind (System.Net.EndPoint localEP) [x00043] in <ae22a4e8f83c41d69684ae7f557133d9>:0 
  at MyNetworkClass.networkCode () [x0003a] 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(PC)

// 代码部分请参考您提供的内容。

Android

// 代码部分请参考您提供的内容。

备注:

  • 所有应用程序都使用相同的端口。

p.s. Android 代码已经在相同应用程序的其他实例之间进行了测试,并且可以在 gradle 模拟器和手机 APK 上正常工作。

提前感谢您,
Ray


<details>
<summary>英文:</summary>

i&#39;m trying to establish a connection between an Android app (made in Android Studio) and a Unity (PC) app to send-recive messages (string vars) as peer-to-peer (either can be server or client)

- Upon attempt to connect to Android&#39;s local IP - i get: 
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 &lt;ae22a4e8f83c41d69684ae7f557133d9&gt;: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()

- Upon attempt to connect to 2 PC apps (to test connection) - i get &quot;

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()


Here are the used scripts:
Unity (PC)

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 &amp;&amp; keepReading &amp;&amp; receiveStream != null)// &amp;&amp; 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 = &quot;&quot;;
    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(&quot;192.168.0.104&quot;);
    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(&quot;IP: &quot; + localEndPoint.Address.ToString() + &quot; | &quot; + myIp.ToString() + &quot; -- Port: &quot; + localEndPoint.Port.ToString() + &quot; | &quot; + VarsStatic.Port);
        // Start listening for connections.
        while (true)
        {
            keepReading = true;

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

            handler = listener.Accept();
            Debug.Log(&quot;Client Connected&quot;);     //It doesn&#39;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(&quot;Received from Server&quot;);

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

                data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
                if (data.IndexOf(&quot;&lt;EOF&gt;&quot;) &gt; -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 &amp;&amp; handler.Connected)
    {
        handler.Disconnect(false);
        Debug.Log(&quot;Disconnected!&quot;);
    }
}

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&#39;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(&quot;Open Camera&quot;)) {
                            messageOn = true;
                            Toast.makeText(getApplicationContext(), &quot;Opening Camera on another client&quot;, Toast.LENGTH_SHORT).show();
                        } else if (message.equals(&quot;Open Gallery&quot;)) {
                            messageOn = true;
                            Toast.makeText(getApplicationContext(), &quot;Opening Gallery on another client&quot;, Toast.LENGTH_SHORT).show();
                        }
                        //

                        if (!messageOn)
                            Toast.makeText(getApplicationContext(), &quot;Message received from client: &quot; + 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&#39;t flood the output with errors
            try {
                Thread.sleep(SleepTime);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }

    }
}

class BackgroundTask extends AsyncTask&lt;String, Void, String&gt; {
    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;
    }
}

Note:
- all are using the same Port

p.s. Android code is tested and working between other instances of the same app (gradle emulator - built to phone apk)

Thank you in advance,
Ray

</details>


huangapple
  • 本文由 发表于 2020年4月7日 19:23:03
  • 转载请务必保留本文链接:https://java.coder-hub.com/61078883.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定