英文:
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'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'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 <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()
- Upon attempt to connect to 2 PC apps (to test connection) - i get "
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 && 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;
}
}
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>
专注分享java语言的经验与见解,让所有开发者获益!
评论