原文地址:传送门

今天苦战了一天,就跟一个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. Locally weighted linear regression(局部加权线性回归)

    (整理自AndrewNG的课件,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 前面几篇博客主要介绍了线性回归的学习算法,那么它有什么不足的地方么 ...

  2. Delphi安装NT服务程序时(不出现提示信息)

    如果我们不加上"/silent",那么Delphi在安装和卸载NT服务程序时候,都会出现一个提示信息,不希望出现这个提示信息,那么使用如下命令: 1,安装:“你的nt程序 /ins ...

  3. JQuery+AJAX实现搜索文本框的输入提示功能

    平时使用谷歌搜索的时候发现只要在文本框里输入部分单词或字母,下面马上会弹出一个相关信息的内容框可供选择.感觉这个功能有较好的用户体验,所以也想在自己的网站上加上这种输入提示框. 实现的原理其实很简单, ...

  4. Transformations 方块转换

    题目是中文题,就不做什么解释了,纯模拟题,主要要搞清楚这几种装换方式下标的变化: 第一种:顺时针旋转90度: c[j][n-i+1]=a[i][j]; 第二种:旋转180度: c[n-i+1][n-j ...

  5. iot 表索引dump《2》

    iot表测试: 在create table语句后面使用organization index,就指定数据表创建结构是IOT.但是在不指定主键Primary Key的情况下,是不允许建表的. create ...

  6. linux pthread之学习篇

    在应用程序编程中,为了不影响与用户交互的性能,通常需要创建新的线程来处理一些比较耗时的. 不影响用户体验的工作.而这又通常分为两种情况: (1)需要临时创建一个线程来做某件特定的事,等事情做完时线程即 ...

  7. hdu 4778 Rabbit Kingdom(减少国家)

    题目链接:hdu 4778 Rabbit Kingdom 题目大意:Alice和Bob玩游戏,有一个炉子.能够将S个同样颜色的宝石换成一个魔法石.如今有B个包,每一个包里有若干个宝石,给出宝石的颜色. ...

  8. 无比奇怪的问题,Runtime报错,程序仍可运行(有可能是线程崩溃,但主程序不崩溃,线程崩溃可能是因为锁使用不当引起的)

    但主界面仍可操作. 我估计是,线程运行崩溃,不影响主界面的运行(如果你不去点击那个确认错误的对话框的话). 仔细分析,我估计是使用锁不当引起的.有2种情况下必崩溃: 1. 对没有上锁的锁进行解锁 2. ...

  9. 【Visual C++】Windows GDI贴图闪烁解决方法

    一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化,所以不可避免在窗口移动或者改变大小的时候出现闪烁. 先来谈谈闪烁产生的原因 原因一:如果熟悉显卡原理的话,调用GDI函数向屏幕输出的 ...

  10. Delphi与Vista提供的UAC控制(1-代表资源编号,24-资源类型为RTMAINIFEST,最后用brcc32编译成资源文件)

    Vista提供的UAC机制,是Vista的新增功能之一.它的主要目的是防止对于操作系统本身的恶意修 改.如果想对于Vista的 系统设置进行改动,必须通过UAC的验 证才能够进行.通过这样的手段,大大 ...