小记:针对目前功能越来越强大的智能手机来说,在PC端支持对手机中的用户数据作同步、备份以及恢复等保护措施的应用已经急需完善。不仅要对数据作保护,而且用户更希望自己的手机跟PC能够一体化,以及和远程服务器的一体化。用户希望在手机端的操作能够转移到PC端,对于PC端大屏幕的电脑来说,完成同样的操作可以大量的节省用户的时间。对于功能强大的手机来说,有近1/2的应用可以在PC端同步。所以对PC端应用的规划要以系统的角度来对待。同时要保证手机端和PC端的主流交互模式应保持一致。个人观点:数据的一体化和管理的多元化是以后发展的一个趋势。下面进行今天的学习,今天的实验室移动端和PC端的数据交互及解析。
1,如何实现移动端和PC端的数据交互?
答:1,蓝牙 2,NFC技术 3,红外 4,Socket.
NFC和蓝牙的异同点:
相同点:都是近距离传输。
不同点: NFC优于红外和蓝牙传输方式。作为一种面向消费者的交易机制,NFC比红外更快、更可靠而且简单得多,不用向红外那样必须严格的对齐才能传输数据。与蓝牙相比,NFC面向近距离交易,适用于交换财务信息或敏感的个人信息等重要数据;蓝牙能够弥补NFC通信距离不足的缺点,适用于较长距离数据通信。因此,NFC和蓝牙互为补充,共同存在。事实上,快捷轻型的NFC 协议可以用于引导两台设备之间的蓝牙配对过程,促进了蓝牙的使用。但是要实现远距离的数据传输那就只能用Socket了,
下面进行代码的分析:
首先在PC上建立服务端Server.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.Threading; namespace TcpServer { class Program { public static Socket serverSocket; static Thread threadSend; static Thread sendDataToClient; static int count = 1; static void Main(string[] args) { //确定端口号 int port = 121; //设定连接IP string host = "192.168.1.100"; //将IP地址字符串转化为IP地址实例 IPAddress ip = IPAddress.Parse(host); //将网络端点表示为 IP 地址和端口号 IPEndPoint ipe = new IPEndPoint(ip, port); //建立Socket //addressFamily 参数指定 Socket 类使用的寻址方案 //socketType 参数指定 Socket 类的类型 //protocolType 参数指定 Socket 使用的协议。 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //socket与本地终结点建立关联 socket.Bind(ipe); while (true) { //开始监听端口 socket.Listen(0); Console.WriteLine("服务已开启,请等待....." + DateTime.Now.ToString() + DateTime.Now.Millisecond.ToString()); //为新建的连接建立新的Socket目的为客户端将要建立连接 serverSocket = socket.Accept(); Console.WriteLine("连接已建立......" + DateTime.Now.ToString() + DateTime.Now.Millisecond.ToString()); Console.WriteLine("客户端IP:"+serverSocket.RemoteEndPoint); string recStr =string.Empty; //定义缓冲区用于接收客户端的数据 byte[] recbyte = new byte[1024]; ReceiveData(); sendDataToClient = new Thread(sendData); sendDataToClient.Start(); } } public static void sendData() { while (true) { Console.WriteLine("send to client\n"); //服务端给客户端回送消息 string strSend = "Hello Android Client!" + DateTime.Now.Second; //string strSend = "HelloClient1HelloClient2HelloClient3HelloClient4HelloClient5HelloClient6HelloClient7HelloClient8HelloClient9HelloClient10HelloClient11HelloClien12HelloClien13HelloClien14HelloClien15HelloClient16"; byte[] sendByte = new byte[1024]; //将发送的字符串转换为byte[] sendByte = UTF8Encoding.UTF8.GetBytes(strSend); //服务端发送数据 serverSocket.Send(sendByte, sendByte.Length, 0); Thread.Sleep(1000); } } #region /// <summary> /// 异步连接 /// </summary> /// <param name="ip"></param> /// <param name="port"></param> /// <param name="clientSocket"></param> public static void Connect(IPAddress ip, int port) { serverSocket.BeginConnect(ip, port, new AsyncCallback(ConnectCallback), serverSocket); } private static void ConnectCallback(IAsyncResult ar) { try { Socket handler = (Socket)ar.AsyncState; handler.EndConnect(ar); } catch (SocketException ex) { throw ex; } } /// <summary> /// 发送数据 /// </summary> /// <param name="data"></param> public static void Send(string data) { //Send(System.Text.Encoding.UTF8.GetBytes(data)); Send(UTF8Encoding.UTF8.GetBytes(data)); } /// <summary> /// 发送数据 /// </summary> /// <param name="byteData"></param> private static void Send(byte[] byteData) { try { int length = byteData.Length; byte[] head = BitConverter.GetBytes(length); byte[] data = new byte[head.Length + byteData.Length]; Array.Copy(head, data, head.Length); Array.Copy(byteData, 0, data, head.Length, byteData.Length); serverSocket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), serverSocket); } catch (SocketException ex) { } } private static void SendCallback(IAsyncResult ar) { try { Socket handler = (Socket)ar.AsyncState; handler.EndSend(ar); } catch (SocketException ex) { throw ex; } } static byte[] MsgBuffer = new byte[128]; /// <summary> /// 接收消息 /// </summary> public static void ReceiveData() { if (serverSocket.ReceiveBufferSize > 0) { serverSocket.BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0, new AsyncCallback(ReceiveCallback), null); } } private static void ReceiveCallback(IAsyncResult ar) { try { int REnd = serverSocket.EndReceive(ar); Console.WriteLine("长度:" + REnd); if (REnd > 0) { byte[] data = new byte[REnd]; Array.Copy(MsgBuffer, 0, data, 0, REnd); int Msglen = data.Length; //在此次可以对data进行按需处理 serverSocket.BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0, new AsyncCallback(ReceiveCallback), null); //Console.WriteLine("接收服务端的信息:{0}", Encoding.ASCII.GetString(MsgBuffer, 0, Msglen)); Console.WriteLine("接收服务端的信息:{0}", UTF8Encoding.UTF8.GetString(data, 0, Msglen)); } else { dispose(); } } catch (SocketException ex) { } } private static void dispose() { try { serverSocket.Shutdown(SocketShutdown.Both); serverSocket.Close(); } catch (Exception ex) { throw ex; } } #endregion } }
移动端使用Unity3D写的脚本挂在mainCamera上,代码如下:
using UnityEngine; using System.Collections; using System.Net.Sockets; using System.Net; using System; using System.Text; using System.IO; public class client : MonoBehaviour { public GUIText text; public GUIText path; public static Socket clientSocket; // Use this for initialization void Start () { //服务器IP string LocalIP = "192.168.1.100"; //端口号 int port = 121; IPAddress ip =IPAddress.Parse(LocalIP); IPEndPoint ipe = new IPEndPoint(ip,port); clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//建立客户端Socket clientSocket.Connect(ipe); StartCoroutine("sendData"); //启动协同程序 StartCoroutine("getInfo"); } // Update is called once per frame void Update () { if(Input.GetKey(KeyCode.Escape)||Input.GetKey(KeyCode.Home)) { Application.Quit(); } } void OnGUI() { if(GUI.Button(new Rect(Screen.width/2-40,30,100,60),"截图")) { StartCoroutine("GetCapture"); } } IEnumerator GetCapture () { yield return new WaitForEndOfFrame(); int width = Screen.width; int height = Screen.height; Texture2D tex = new Texture2D (width, height, TextureFormat.RGB24, false); tex.ReadPixels (new Rect (0, 0, width, height), 0, 0, true); byte[] imagebytes = tex.EncodeToPNG ();//转化为png图 tex.Compress (false);//对屏幕缓存进行压缩 //image.mainTexture = tex;//对屏幕缓存进行显示(缩略图) string PicPath="storage"; File.WriteAllBytes (Application.persistentDataPath+"/"+Time.time+ ".png", imagebytes);//存储png图 path.text = Application.persistentDataPath+"/"; } /// <summary> /// 向服务器发送消息 /// </summary> /// <returns>The data.</returns> public IEnumerator sendData() { int i=0; while(true) { string sendStr = i.ToString()+"你好 server,I am Android"; byte[] sendBytes = UTF8Encoding.UTF8.GetBytes(sendStr); clientSocket.Send(sendBytes); i++; yield return new WaitForSeconds(1f); } } /// <summary> /// 得到服务器回应 /// </summary> /// <returns>The info.</returns> public IEnumerator getInfo() { while(true) { byte[] revBytes = new byte[1024]; int bytes = clientSocket.Receive(revBytes, revBytes.Length, 0); string revStr =""; //revStr += Encoding.ASCII.GetString(revBytes, 0, bytes); revStr += UTF8Encoding.UTF8.GetString(revBytes,0,bytes); Debug.Log ("接收到服务器消息:"+revStr); text.text = "From Server:"+revStr; yield return null; } } }
服务器端运行结果:
服务器回送消息代码:string strSend = "Hello Android Client!" + DateTime.Now.Second;
局域网下测试没有什么问题,以后无论是做应用还是网络游戏肯定少不了的是Socket网络数据传输,多了解点网络知识还是很有必要的尤其是TCP协议,如有错误,欢迎指正。