[Unity3d]socket通信 切换到web版本时报错SecurityException解决办法

寵の児 提交于 2020-03-02 08:27:41

今天苦战了一天,就跟一个Unity切换到web平台的socket通信出错苦苦纠缠了一天,问了好多大牛,但他们的回复都是我没搞过web平台下的通信或者我只专研于pc或者移动平台。看来没办法了,只能自己硬着头皮往下探究了,貌似之前flash开发就是这样,凡事碰到要跟服务器通信的都会出现老大难的权限不足的错误。

具体错误如下:

SecurityException: Unable to connect, as no valid crossdomain policy was found
System.Net.Sockets.Socket.Connect_internal (IntPtr sock, System.Net.SocketAddress sa, System.Int32& error, Boolean requireSocketPolicyFile)
System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP, Boolean requireSocketPolicy)
System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP)
System.Net.Sockets.UdpClient.DoConnect (System.Net.IPEndPoint endPoint)
System.Net.Sockets.UdpClient.Connect (System.Net.IPEndPoint endPoint)

System.Net.Sockets.UdpClient.Connect (System.String hostname, Int32 port)

这印象太深刻了,搞得我快吐血了,但这时终于搞定了,真欣慰。

之前我写过一篇有关于www访问web服务器的相同的问题,但那个稍微好解决一点,只要参考着官方文档就能解决了,我在这之前也有解决过该类问题的博客,官方的文档是:http://docs.unity3d.com/Documentation/Manual/SecuritySandbox.html,虽然全是英文,但学搞IT的看不了英文还真的很蛋疼,谁叫老美IT发达的呢,希望什么时候,互联网上技术先进的博客或者论坛都是中文的,当然有点想当然了,如果真有那么一天不知道是什么时候呢?!只能期待,下面回归正题。

我创建的服务器是C#的控制台程序,在项目工程文件里面添加以下crossdomain.xml文件,然后打开843的端口,切记这个必须打开,不然就会报错,客户端是通过这个端口来查找配置文件的。然后在运行unity切换到web平台就不会报错了。

怎么打开843端口呢?

解决办法:我们在unity的安装目录下找到一个sockpol.exe的这个一个工具,具体路径是在“...\Unity\Editor\Data\Tools\SocketPolicyServer“路径下有sockpol.exe和它的源码。如果你的服务器端是Windows平台的话,直接Copy一个sockpol.exe到服务器端,在CMD中执行
sockpol.exe --all
即可为服务器端配置好Security SandBox安全策略。

运行了之后我们会看到Hit Return to stop the server,然后如果有一个人连接上的话就会提示

incoming connection

got policy request,sending response

如果做到这一步 恭喜你能连接了。

测试地址:http://114.92.230.107/aspnet_client/system_web/chat/newchat.html

还有一个问题就是端口衍射的问题,要绑定外网IP和内网服务器的端口,不然的话外网还是不能使用聊天功能的,只能看到页面而已!

源码以后有空再上传,这时困了,睡觉觉!




源码:

Server端:

ChatClient:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Collections;  
  6. using System.Net.Sockets;  
  7.   
  8. namespace TestServer  
  9. {  
  10.     class ChatClient  
  11.     {  
  12.         public static Hashtable ALLClients = new Hashtable(); // 客户列表  
  13.   
  14.         private TcpClient _client;  // 客户端实体  
  15.         public string _clientIP;   // 客户端IP  
  16.         private string _clientNick; // 客户端昵称  
  17.   
  18.         private byte[] data;        // 消息数据  
  19.   
  20.         private bool ReceiveNick = true;  
  21.   
  22.         public ChatClient(TcpClient client)  
  23.         {  
  24.             this._client = client;  
  25.   
  26.             this._clientIP = client.Client.RemoteEndPoint.ToString();  
  27.   
  28.             // 把当前客户端实例添加到客户列表当中  
  29.             ALLClients.Add(this._clientIP, this);  
  30.   
  31.             data = new byte[this._client.ReceiveBufferSize];  
  32.   
  33.             // 从服务端获取消息  
  34.             client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);  
  35.         }  
  36.   
  37.         // 从客戶端获取消息  
  38.         public void ReceiveMessage(IAsyncResult ar)  
  39.         {  
  40.             int bytesRead;  
  41.   
  42.             try  
  43.             {  
  44.                 lock (this._client.GetStream())  
  45.                 {  
  46.                     bytesRead = this._client.GetStream().EndRead(ar);  
  47.                 }  
  48.   
  49.                 if (bytesRead < 1)  
  50.                 {  
  51.                     ALLClients.Remove(this._clientIP);  
  52.   
  53.                     Broadcast(this._clientNick + " has left the chat");  
  54.   
  55.                     return;  
  56.                 }  
  57.                 else  
  58.                 {  
  59.                     string messageReceived = System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);  
  60.   
  61.                     if (ReceiveNick)  
  62.                     {  
  63.                         this._clientNick = messageReceived;  
  64.   
  65.                         Broadcast(this._clientNick + " has joined the chat.");  
  66.   
  67.                         //this.sendMessage("hello");  
  68.   
  69.                         ReceiveNick = false;  
  70.                     }  
  71.                     else  
  72.                     {  
  73.                         Broadcast(this._clientNick + ">" + messageReceived);  
  74.   
  75.                     }  
  76.                 }  
  77.   
  78.                 lock (this._client.GetStream())  
  79.                 {  
  80.                     this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);  
  81.                 }  
  82.             }  
  83.             catch (Exception ex)  
  84.             {  
  85.                 ALLClients.Remove(this._clientIP);  
  86.   
  87.                 Broadcast(this._clientNick + " has left the chat.");  
  88.             }  
  89.         }  
  90.   
  91.         // 向客戶端发送消息  
  92.         public void sendMessage(string message)  
  93.         {  
  94.             try  
  95.             {  
  96.                 System.Net.Sockets.NetworkStream ns;  
  97.   
  98.                 lock (this._client.GetStream())  
  99.                 {  
  100.                     ns = this._client.GetStream();  
  101.                 }  
  102.   
  103.                 // 对信息进行编码  
  104.                 byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(message);  
  105.   
  106.                 ns.Write(bytesToSend, 0, bytesToSend.Length);  
  107.                 ns.Flush();  
  108.             }  
  109.             catch (Exception ex)  
  110.             {  
  111.   
  112.             }  
  113.         }  
  114.   
  115.         // 向客户端广播消息  
  116.         public void Broadcast(string message)  
  117.         {  
  118.             Console.WriteLine(message);  
  119.   
  120.             foreach (DictionaryEntry c in ALLClients)  
  121.             {  
  122.                 ((ChatClient)(c.Value)).sendMessage(message + Environment.NewLine);  
  123.             }  
  124.         }  
  125.   
  126.     }  
  127. }  

Program:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Net.Sockets;  
  6. using TestServer;  
  7.   
  8. namespace ConsoleApplication1  
  9. {  
  10.     class Program  
  11.     {  
  12.         //设置连接端口  
  13.         const int portNo = 5001;  
  14.         static void Main(string[] args)  
  15.         {  
  16.             // 初始化服务器IP  
  17.             System.Net.IPAddress localAdd = System.Net.IPAddress.Parse("114.92.245.173");  
  18.   
  19.             // 创建TCP侦听器  
  20.             TcpListener listener = new TcpListener(localAdd, portNo);  
  21.   
  22.             //开始启动监听  
  23.             listener.Start();  
  24.   
  25.             // 显示服务器启动信息  
  26.             Console.WriteLine("Server is starting...\n");  
  27.   
  28.             // 循环接受客户端的连接请求  
  29.             while (true)  
  30.             {  
  31.                 ChatClient user = new ChatClient(listener.AcceptTcpClient());  
  32.   
  33.                 // 显示连接客户端的IP与端口  
  34.                 Console.WriteLine(user._clientIP + " is joined...\n");  
  35.             }  
  36.         }  
  37.     }  
  38. }  

Client端:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. using System;  
  5. using System.Collections.Generic;  
  6. using System.ComponentModel;  
  7. using System.Text;  
  8. using System.Net.Sockets;  
  9.   
  10. public class ClientHandler : MonoBehaviour  
  11. {  
  12.     //端口号  
  13.     const int portNo = 50001;  
  14.     private TcpClient _client; //当前socket客户端  
  15.     byte[] data;  
  16.   
  17.     // Use this for initialization  
  18.     void Start()  
  19.     {  
  20.   
  21.     }  
  22.   
  23.     // Update is called once per frame  
  24.     void Update()  
  25.     {  
  26.   
  27.     }  
  28.   
  29.     //名字  
  30.     public string nickName = "";  
  31.     //信息  
  32.     public string message = "";  
  33.     //要发送的消息  
  34.     public string sendMsg = "";  
  35.   
  36.     void OnGUI()  
  37.     {  
  38.         //用户名  
  39.         nickName = GUI.TextField(new Rect(10, 10, 100, 20), nickName);  
  40.         //聊天消息  
  41.         message = GUI.TextArea(new Rect(10, 40, 300, 200), message);  
  42.         //发送的消息  
  43.         sendMsg = GUI.TextField(new Rect(10, 250, 210, 20), sendMsg);  
  44.   
  45.         if (GUI.Button(new Rect(120, 10, 150, 20), "填写用户名之后连接"))  
  46.         {  
  47.             //创建一个新的连接  
  48.             this._client = new TcpClient();  
  49.             this._client.Connect("114.92.245.173", portNo);  
  50.             if(this._client.Connected)  
  51.             {  
  52.                 Debug.Log("登陆成功");  
  53.             }  
  54.             //接受多大的字节数据  
  55.             data = new byte[this._client.ReceiveBufferSize];  
  56.   
  57.             //发送用户名  
  58.             SendMessage(nickName);  
  59.               
  60.             this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);  
  61.         };  
  62.   
  63.         if (GUI.Button(new Rect(230, 250, 80, 20), "发送"))  
  64.         {  
  65.             SendMessage(sendMsg);  
  66.             sendMsg = "";  
  67.         };  
  68.     }  
  69.   
  70.     //发送消息(ASCII码)  
  71.     public void SendMessage(string message)  
  72.     {  
  73.         try  
  74.         {  
  75.             //创建流  
  76.             NetworkStream ns = this._client.GetStream();  
  77.   
  78.             byte[] data = System.Text.Encoding.ASCII.GetBytes(message);  
  79.   
  80.             ns.Write(data, 0, data.Length);   
  81.             ns.Flush();  
  82.         }  
  83.         catch (Exception ex)  
  84.         {  
  85.             //MessageBox.Show(ex.ToString());  
  86.         }  
  87.     }  
  88.   
  89.     //接受消息  
  90.     public void ReceiveMessage(IAsyncResult ar)  
  91.     {  
  92.         try  
  93.         {  
  94.             int bytesRead;  
  95.   
  96.             bytesRead = this._client.GetStream().EndRead(ar);  
  97.               
  98.             //如果没有信息则返回  
  99.             if (bytesRead < 1)  
  100.             {  
  101.                 return;  
  102.             }  
  103.             else  
  104.             {  
  105.   
  106.                 Debug.Log(System.Text.Encoding.ASCII.GetString(data, 0, bytesRead));  
  107.                 //message是不断的加的,然后显示到中间的框中  
  108.                 message += System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);  
  109.             }  
  110.               
  111.             //开始读取接收到的信息保存到data中  
  112.             this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);  
  113.   
  114.         }  
  115.         catch (Exception ex)  
  116.         {  
  117.   
  118.         }  
  119.           
  120.     }  
  121. }  

效果:



项目源文件:

http://download.csdn.net/detail/s10141303/6618107

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!