原文地址:传送门

今天苦战了一天,就跟一个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 ?

  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. namespace TestServer
  8. {
  9. class ChatClient
  10. {
  11. public static Hashtable ALLClients = new Hashtable(); // 客户列表
  12. private TcpClient _client; // 客户端实体
  13. public string _clientIP; // 客户端IP
  14. private string _clientNick; // 客户端昵称
  15. private byte[] data; // 消息数据
  16. private bool ReceiveNick = true;
  17. public ChatClient(TcpClient client)
  18. {
  19. this._client = client;
  20. this._clientIP = client.Client.RemoteEndPoint.ToString();
  21. // 把当前客户端实例添加到客户列表当中
  22. ALLClients.Add(this._clientIP, this);
  23. data = new byte[this._client.ReceiveBufferSize];
  24. // 从服务端获取消息
  25. client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
  26. }
  27. // 从客戶端获取消息
  28. public void ReceiveMessage(IAsyncResult ar)
  29. {
  30. int bytesRead;
  31. try
  32. {
  33. lock (this._client.GetStream())
  34. {
  35. bytesRead = this._client.GetStream().EndRead(ar);
  36. }
  37. if (bytesRead < 1)
  38. {
  39. ALLClients.Remove(this._clientIP);
  40. Broadcast(this._clientNick + " has left the chat");
  41. return;
  42. }
  43. else
  44. {
  45. string messageReceived = System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);
  46. if (ReceiveNick)
  47. {
  48. this._clientNick = messageReceived;
  49. Broadcast(this._clientNick + " has joined the chat.");
  50. //this.sendMessage("hello");
  51. ReceiveNick = false;
  52. }
  53. else
  54. {
  55. Broadcast(this._clientNick + ">" + messageReceived);
  56. }
  57. }
  58. lock (this._client.GetStream())
  59. {
  60. this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
  61. }
  62. }
  63. catch (Exception ex)
  64. {
  65. ALLClients.Remove(this._clientIP);
  66. Broadcast(this._clientNick + " has left the chat.");
  67. }
  68. }
  69. // 向客戶端发送消息
  70. public void sendMessage(string message)
  71. {
  72. try
  73. {
  74. System.Net.Sockets.NetworkStream ns;
  75. lock (this._client.GetStream())
  76. {
  77. ns = this._client.GetStream();
  78. }
  79. // 对信息进行编码
  80. byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(message);
  81. ns.Write(bytesToSend, 0, bytesToSend.Length);
  82. ns.Flush();
  83. }
  84. catch (Exception ex)
  85. {
  86. }
  87. }
  88. // 向客户端广播消息
  89. public void Broadcast(string message)
  90. {
  91. Console.WriteLine(message);
  92. foreach (DictionaryEntry c in ALLClients)
  93. {
  94. ((ChatClient)(c.Value)).sendMessage(message + Environment.NewLine);
  95. }
  96. }
  97. }
  98. }

Program:

[csharp] view plain copy print ?

  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. namespace ConsoleApplication1
  8. {
  9. class Program
  10. {
  11. //设置连接端口
  12. const int portNo = 5001;
  13. static void Main(string[] args)
  14. {
  15. // 初始化服务器IP
  16. System.Net.IPAddress localAdd = System.Net.IPAddress.Parse("114.92.245.173");
  17. // 创建TCP侦听器
  18. TcpListener listener = new TcpListener(localAdd, portNo);
  19. //开始启动监听
  20. listener.Start();
  21. // 显示服务器启动信息
  22. Console.WriteLine("Server is starting...\n");
  23. // 循环接受客户端的连接请求
  24. while (true)
  25. {
  26. ChatClient user = new ChatClient(listener.AcceptTcpClient());
  27. // 显示连接客户端的IP与端口
  28. Console.WriteLine(user._clientIP + " is joined...\n");
  29. }
  30. }
  31. }
  32. }

Client端:

[csharp] view plain copy print ?

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

效果:

项目源文件:

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

Unity3d socket通信 切换到web版本时报错SecurityException解决办法的更多相关文章

  1. 关于pycharm中安装第三方库时报错的解决办法(一)

    记录自己的生活!   一.事发背景 在pycharm中直接安装第三方库时因为版本问题总是无法安装成功,事情不大,但是很重要.   二.经过 最开始我自己电脑上安装了Python3.6和Python2. ...

  2. 使用idea时jsp中使用out.print();时报错的解决办法

    在用Maven创建web项目时 在jsp页面中out.print();老是报错 这边print显示红色出错因为这边使用的是JSP的API并不是Servlet的,但是可以运行,所以我们只要导包就完事其实 ...

  3. 本机连接虚拟机Oracle时报错的解决办法

    虚拟机安装了Oracle服务器(桌面类)和客户端,里面使用plsql连接自己没有问题. 在本机连接虚拟机没有成功.虚拟机的地址是192.168.126.132,已经确认本机能ping通虚拟机. 先是报 ...

  4. Error Fix – Replication subscriber does not exist on the server anymore(删除Replication时报错的解决办法)

    Recently one of my client has faced weird situation related to SQL Server Replication. Their main da ...

  5. AS启动模拟器时报错的解决办法

    问题描述 AS安装后之后,在AVD manager 中创建了一个模拟器,并且其他的配置都正确,但是在点击run时却出现了如下的错误: 这个问题一直在报Error while waiting for d ...

  6. python3 安装 pyinstaller 时报错的解决办法

    如上图所示,在安装的过程中发现是所关联的一个 future模块安装失败,庵后我有单独安装了一下这个future,发现还是失败 然后在网上寻找解决办法,最后找到了这个指令,pip install fut ...

  7. 使用yum安装php*时报错的解决办法

    # yum -y install php* 注意: php53-odbc64-5.3.3-2.el5.x86_64 from base has depsolving problems  -->  ...

  8. 运行java web项目时报错:Several ports (8005, 8080, 8009) required

    运行java web项目时报错:Several ports (8005, 8080, 8009) required 如下图 之所以报上面的错误是因为安装Tomcat的时候,已经把端口8005,8080 ...

  9. centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'

    centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'的解决办法 3.7版本需要一个新的包libffi-de ...

随机推荐

  1. grails一对一关联关系

    一对一关联关系开发中用的没有一对多那么广泛.可是我认为掌握以下还是有必要的.一对一关联关系有一张表存在外键,引用的通常是主表的主键.grails也对一对一关联关系提供了非常好的支持.配置也是简单的不得 ...

  2. JavaScript的原型继承

    JavaScript是一门面向对象的语言.在JavaScript中有一句很经典的话,万物皆对象.既然是面向对象的,那就有面向对象的三大特征:封装.继承.多态.这里讲的是JavaScript的继承,其他 ...

  3. .Net 配置文件——继承ConfigurationSection实现自己定义处理类处理自己定义配置节点

    除了使用继承IConfigurationSectionHandler的方法定义处理自己定义节点的类.还能够通过继承ConfigurationSection类实现相同效果. 首先说下.Net配置文件里一 ...

  4. 百度地图 javascript相关Bug搜集

    一 在手机里用百度地图js版做webapp   bug集合 1 之前用2.0版本的时候发现只要地图添加了覆盖物,无论数量多少,当地图放大到很小的范围时候,会卡死 1.1 当时处理办法:将版本降低至1. ...

  5. Lucene.Net 2.3.1开发介绍 —— 三、索引(七)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(七) 5.IndexWriter 索引这部分最后讲的是IndexWriter.如果说前面提到的都是数据的结构,那么IndexWriter ...

  6. 七个你无法忽视的Git使用技巧(转)

    与其他技术相比,Git应该拯救了更多开发人员的饭碗.只要你经常使用Git保存自己的工作,你就一直有机会可以将代码退回到之前的状态,因此就可以挽回那些你深夜里迷迷糊糊犯下的错误. 尽管这么说,Git的命 ...

  7. adb 之android的神器am

    am命令,am全称activity manager,你能使用am去模拟各种系统的行为,例如去启动一个activity,强制停止进程,发送广播进程,修改设备屏幕属性等等 命令窗口通过adb shell ...

  8. tbb 线程安全concurrent_queue的性能

    tbb实现了线程安全的queue,这样程序员既可以不用和那些lock,mutex,criticalsection打交道,又大大提高性能,太给力了..比较的结果见代码中的注释.结果可以看出代码足足少一半 ...

  9. 公司内网Debian Server上的openvpnserver搭建并通过SSH隧道转发到广域网

    因为戴维营公司在长沙的学员,研发人员和北京的研发人员须要协同研发,故须要让北京的兄弟们增加到长沙办公室的内网,訪问版本号 管理server,于是採用在内网server上搭建一个OpenVPN服务,并把 ...

  10. 实例:怎样使用 Netty 下载文件

    本实例主要參考的是官网的examples:点击这里 使用场景:client向Netty请求一个文件,Netty服务端下载指定位置文件到client. 本实例使用的是Http协议,当然,能够通过简单的改 ...