Unity3d socket通信 切换到web版本时报错SecurityException解决办法
原文地址:传送门
今天苦战了一天,就跟一个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 ?
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Collections;
- using System.Net.Sockets;
- namespace TestServer
- {
- class ChatClient
- {
- public static Hashtable ALLClients = new Hashtable(); // 客户列表
- private TcpClient _client; // 客户端实体
- public string _clientIP; // 客户端IP
- private string _clientNick; // 客户端昵称
- private byte[] data; // 消息数据
- private bool ReceiveNick = true;
- public ChatClient(TcpClient client)
- {
- this._client = client;
- this._clientIP = client.Client.RemoteEndPoint.ToString();
- // 把当前客户端实例添加到客户列表当中
- ALLClients.Add(this._clientIP, this);
- data = new byte[this._client.ReceiveBufferSize];
- // 从服务端获取消息
- client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
- }
- // 从客戶端获取消息
- public void ReceiveMessage(IAsyncResult ar)
- {
- int bytesRead;
- try
- {
- lock (this._client.GetStream())
- {
- bytesRead = this._client.GetStream().EndRead(ar);
- }
- if (bytesRead < 1)
- {
- ALLClients.Remove(this._clientIP);
- Broadcast(this._clientNick + " has left the chat");
- return;
- }
- else
- {
- string messageReceived = System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);
- if (ReceiveNick)
- {
- this._clientNick = messageReceived;
- Broadcast(this._clientNick + " has joined the chat.");
- //this.sendMessage("hello");
- ReceiveNick = false;
- }
- else
- {
- Broadcast(this._clientNick + ">" + messageReceived);
- }
- }
- lock (this._client.GetStream())
- {
- this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
- }
- }
- catch (Exception ex)
- {
- ALLClients.Remove(this._clientIP);
- Broadcast(this._clientNick + " has left the chat.");
- }
- }
- // 向客戶端发送消息
- public void sendMessage(string message)
- {
- try
- {
- System.Net.Sockets.NetworkStream ns;
- lock (this._client.GetStream())
- {
- ns = this._client.GetStream();
- }
- // 对信息进行编码
- byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(message);
- ns.Write(bytesToSend, 0, bytesToSend.Length);
- ns.Flush();
- }
- catch (Exception ex)
- {
- }
- }
- // 向客户端广播消息
- public void Broadcast(string message)
- {
- Console.WriteLine(message);
- foreach (DictionaryEntry c in ALLClients)
- {
- ((ChatClient)(c.Value)).sendMessage(message + Environment.NewLine);
- }
- }
- }
- }
Program:
[csharp] view plain copy print ?
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net.Sockets;
- using TestServer;
- namespace ConsoleApplication1
- {
- class Program
- {
- //设置连接端口
- const int portNo = 5001;
- static void Main(string[] args)
- {
- // 初始化服务器IP
- System.Net.IPAddress localAdd = System.Net.IPAddress.Parse("114.92.245.173");
- // 创建TCP侦听器
- TcpListener listener = new TcpListener(localAdd, portNo);
- //开始启动监听
- listener.Start();
- // 显示服务器启动信息
- Console.WriteLine("Server is starting...\n");
- // 循环接受客户端的连接请求
- while (true)
- {
- ChatClient user = new ChatClient(listener.AcceptTcpClient());
- // 显示连接客户端的IP与端口
- Console.WriteLine(user._clientIP + " is joined...\n");
- }
- }
- }
- }
Client端:
[csharp] view plain copy print ?
- using UnityEngine;
- using System.Collections;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Text;
- using System.Net.Sockets;
- public class ClientHandler : MonoBehaviour
- {
- //端口号
- const int portNo = 50001;
- private TcpClient _client; //当前socket客户端
- byte[] data;
- // Use this for initialization
- void Start()
- {
- }
- // Update is called once per frame
- void Update()
- {
- }
- //名字
- public string nickName = "";
- //信息
- public string message = "";
- //要发送的消息
- public string sendMsg = "";
- void OnGUI()
- {
- //用户名
- nickName = GUI.TextField(new Rect(10, 10, 100, 20), nickName);
- //聊天消息
- message = GUI.TextArea(new Rect(10, 40, 300, 200), message);
- //发送的消息
- sendMsg = GUI.TextField(new Rect(10, 250, 210, 20), sendMsg);
- if (GUI.Button(new Rect(120, 10, 150, 20), "填写用户名之后连接"))
- {
- //创建一个新的连接
- this._client = new TcpClient();
- this._client.Connect("114.92.245.173", portNo);
- if(this._client.Connected)
- {
- Debug.Log("登陆成功");
- }
- //接受多大的字节数据
- data = new byte[this._client.ReceiveBufferSize];
- //发送用户名
- SendMessage(nickName);
- this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
- };
- if (GUI.Button(new Rect(230, 250, 80, 20), "发送"))
- {
- SendMessage(sendMsg);
- sendMsg = "";
- };
- }
- //发送消息(ASCII码)
- public void SendMessage(string message)
- {
- try
- {
- //创建流
- NetworkStream ns = this._client.GetStream();
- byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
- ns.Write(data, 0, data.Length);
- ns.Flush();
- }
- catch (Exception ex)
- {
- //MessageBox.Show(ex.ToString());
- }
- }
- //接受消息
- public void ReceiveMessage(IAsyncResult ar)
- {
- try
- {
- int bytesRead;
- bytesRead = this._client.GetStream().EndRead(ar);
- //如果没有信息则返回
- if (bytesRead < 1)
- {
- return;
- }
- else
- {
- Debug.Log(System.Text.Encoding.ASCII.GetString(data, 0, bytesRead));
- //message是不断的加的,然后显示到中间的框中
- message += System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);
- }
- //开始读取接收到的信息保存到data中
- this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
- }
- catch (Exception ex)
- {
- }
- }
- }
效果:
项目源文件:
http://download.csdn.net/detail/s10141303/6618107
Unity3d socket通信 切换到web版本时报错SecurityException解决办法的更多相关文章
- 关于pycharm中安装第三方库时报错的解决办法(一)
记录自己的生活! 一.事发背景 在pycharm中直接安装第三方库时因为版本问题总是无法安装成功,事情不大,但是很重要. 二.经过 最开始我自己电脑上安装了Python3.6和Python2. ...
- 使用idea时jsp中使用out.print();时报错的解决办法
在用Maven创建web项目时 在jsp页面中out.print();老是报错 这边print显示红色出错因为这边使用的是JSP的API并不是Servlet的,但是可以运行,所以我们只要导包就完事其实 ...
- 本机连接虚拟机Oracle时报错的解决办法
虚拟机安装了Oracle服务器(桌面类)和客户端,里面使用plsql连接自己没有问题. 在本机连接虚拟机没有成功.虚拟机的地址是192.168.126.132,已经确认本机能ping通虚拟机. 先是报 ...
- 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 ...
- AS启动模拟器时报错的解决办法
问题描述 AS安装后之后,在AVD manager 中创建了一个模拟器,并且其他的配置都正确,但是在点击run时却出现了如下的错误: 这个问题一直在报Error while waiting for d ...
- python3 安装 pyinstaller 时报错的解决办法
如上图所示,在安装的过程中发现是所关联的一个 future模块安装失败,庵后我有单独安装了一下这个future,发现还是失败 然后在网上寻找解决办法,最后找到了这个指令,pip install fut ...
- 使用yum安装php*时报错的解决办法
# yum -y install php* 注意: php53-odbc64-5.3.3-2.el5.x86_64 from base has depsolving problems --> ...
- 运行java web项目时报错:Several ports (8005, 8080, 8009) required
运行java web项目时报错:Several ports (8005, 8080, 8009) required 如下图 之所以报上面的错误是因为安装Tomcat的时候,已经把端口8005,8080 ...
- centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'
centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'的解决办法 3.7版本需要一个新的包libffi-de ...
随机推荐
- Locally weighted linear regression(局部加权线性回归)
(整理自AndrewNG的课件,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 前面几篇博客主要介绍了线性回归的学习算法,那么它有什么不足的地方么 ...
- Delphi安装NT服务程序时(不出现提示信息)
如果我们不加上"/silent",那么Delphi在安装和卸载NT服务程序时候,都会出现一个提示信息,不希望出现这个提示信息,那么使用如下命令: 1,安装:“你的nt程序 /ins ...
- JQuery+AJAX实现搜索文本框的输入提示功能
平时使用谷歌搜索的时候发现只要在文本框里输入部分单词或字母,下面马上会弹出一个相关信息的内容框可供选择.感觉这个功能有较好的用户体验,所以也想在自己的网站上加上这种输入提示框. 实现的原理其实很简单, ...
- Transformations 方块转换
题目是中文题,就不做什么解释了,纯模拟题,主要要搞清楚这几种装换方式下标的变化: 第一种:顺时针旋转90度: c[j][n-i+1]=a[i][j]; 第二种:旋转180度: c[n-i+1][n-j ...
- iot 表索引dump《2》
iot表测试: 在create table语句后面使用organization index,就指定数据表创建结构是IOT.但是在不指定主键Primary Key的情况下,是不允许建表的. create ...
- linux pthread之学习篇
在应用程序编程中,为了不影响与用户交互的性能,通常需要创建新的线程来处理一些比较耗时的. 不影响用户体验的工作.而这又通常分为两种情况: (1)需要临时创建一个线程来做某件特定的事,等事情做完时线程即 ...
- hdu 4778 Rabbit Kingdom(减少国家)
题目链接:hdu 4778 Rabbit Kingdom 题目大意:Alice和Bob玩游戏,有一个炉子.能够将S个同样颜色的宝石换成一个魔法石.如今有B个包,每一个包里有若干个宝石,给出宝石的颜色. ...
- 无比奇怪的问题,Runtime报错,程序仍可运行(有可能是线程崩溃,但主程序不崩溃,线程崩溃可能是因为锁使用不当引起的)
但主界面仍可操作. 我估计是,线程运行崩溃,不影响主界面的运行(如果你不去点击那个确认错误的对话框的话). 仔细分析,我估计是使用锁不当引起的.有2种情况下必崩溃: 1. 对没有上锁的锁进行解锁 2. ...
- 【Visual C++】Windows GDI贴图闪烁解决方法
一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化,所以不可避免在窗口移动或者改变大小的时候出现闪烁. 先来谈谈闪烁产生的原因 原因一:如果熟悉显卡原理的话,调用GDI函数向屏幕输出的 ...
- Delphi与Vista提供的UAC控制(1-代表资源编号,24-资源类型为RTMAINIFEST,最后用brcc32编译成资源文件)
Vista提供的UAC机制,是Vista的新增功能之一.它的主要目的是防止对于操作系统本身的恶意修 改.如果想对于Vista的 系统设置进行改动,必须通过UAC的验 证才能够进行.通过这样的手段,大大 ...