針對目前功能越來越強大的智能手機來說,在PC端支持對手機中的用戶數(shù)據(jù)作同步、備份以及恢復等保護措施的應用已經急需完善。不僅要對數(shù)據(jù)作保護,而且用戶更希望自己的手機跟PC能夠一體化,以及和遠程服務器的一體化。用戶希望在手機端的操作能夠轉移到PC端,對于PC端大屏幕的電腦來說,完成同樣的操作可以大量的節(jié)省用戶的時間。對于功能強大的手機來說,有近1/2的應用可以在PC端同步。所以對PC端應用的規(guī)劃要以系統(tǒng)的角度來對待。同時要保證手機端和PC端的主流交互模式應保持一致。
個人觀點:數(shù)據(jù)的一體化和管理的多元化是以后發(fā)展的一個趨勢。下面進行今天的學習,今天的實驗室移動端和PC端的數(shù)據(jù)交互及解析。
1,如何實現(xiàn)移動端和PC端的數(shù)據(jù)交互?
答:1,藍牙 2,NFC技術 3,紅外 4,Socket.
NFC和藍牙的異同點:
相同點:都是近距離傳輸。
不同點: NFC優(yōu)于紅外和藍牙傳輸方式。作為一種面向消費者的交易機制,NFC比紅外更快、更可靠而且簡單得多,不用向紅外那樣必須嚴格的對齊才能傳輸數(shù)據(jù)。與藍牙相比,NFC面向近距離交易,適用于交換財務信息或敏感的個人信息等重要數(shù)據(jù);藍牙能夠彌補NFC通信距離不足的缺點,適用于較長距離數(shù)據(jù)通信。因此,NFC和藍牙互為補充,共同存在。事實上,快捷輕型的NFC 協(xié)議可以用于引導兩臺設備之間的藍牙配對過程,促進了藍牙的使用。但是要實現(xiàn)遠距離的數(shù)據(jù)傳輸那就只能用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 參數(shù)指定 Socket 類使用的尋址方案
//socketType 參數(shù)指定 Socket 類的類型
//protocolType 參數(shù)指定 Socket 使用的協(xié)議。
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//socket與本地終結點建立關聯(lián)
socket.Bind(ipe);
while (true)
{
//開始監(jiān)聽端口
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;
//定義緩沖區(qū)用于接收客戶端的數(shù)據(jù)
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];
//將發(fā)送的字符串轉換為byte[]
sendByte = UTF8Encoding.UTF8.GetBytes(strSend);
//服務端發(fā)送數(shù)據(jù)
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>
/// 發(fā)送數(shù)據(jù)
/// </summary>
/// <param name="data"></param>
public static void Send(string data)
{
//Send(System.Text.Encoding.UTF8.GetBytes(data));
Send(UTF8Encoding.UTF8.GetBytes(data));
}
/// <summary>
/// 發(fā)送數(shù)據(jù)
/// </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"); //啟動協(xié)同程序
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?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg==,t_20", imagebytes);//存儲png圖
path.text = Application.persistentDataPath+"/";
}
/// <summary>
/// 向服務器發(fā)送消息
/// </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網絡數(shù)據(jù)傳輸,多了解點網絡知識還是很有必要的尤其是TCP協(xié)議,如有錯誤,歡迎指正,后續(xù)會更新