菜鳥開發—— c# 基於藍牙的手機五子棋遊戲開發(二)

 

二:技術問題:

      A、藍牙設備的操作

            利用藍牙的點對點通訊技術,對智能機的藍牙藍牙設備進行操作,對於從未接觸過手機開發的我來說,又是一大難題。比如像:

    1.  打開手機的藍牙設備並使其對外可見;

    2.  搜尋周圍的藍牙設備;

    3.  嘗試連接指定的藍牙設備;

    4.  監聽並接收數據與發送數據

    初步瞭解了一下, 我們可以裏面要調用BluetoothAPIbtdrt.dll),來實現該功能,同時我們也可以使用串口(串口: 計算機上一種非常通用設備通信的協議,同時也是儀器儀表的一個普遍的通信協議)編程的原理,來實現信息的通訊。當知道藍牙信息傳輸同樣是通過發送(BIT)字節來實現的。我們的五子棋的實現原理就出來,因爲作爲藍牙手機,每一臺手機就是一個服務器,在這裏沒有服務機與客戶機的區別的,當一臺手機做了一次操作,就向另一臺手機發送數據,告訴它自己做了什麼,你接下來該做什麼。在這裏,我們該如何實現呢?如何解決上面的問題呢?

 

    

      32feet.NET 2.3
    在解決問題之前,有必要先介紹32feet.NET 2.3。它是Shared—Source項目,支持CF.net 2.0以及桌面版本.NET framework,提供短距離領域(personal area networking technologie)的通信功能,支持bluetooth,Infrared(IrDA)紅外。(參考:http://dev.chinamobile.com/cmdn/wiki/index.php?doc-view-2578.html 這裏面提供了 32feet.NET 2.3的下載地址和使用方法),值得注意的是 32feet.NET 2.3是需要進行安裝的,在安裝過後,在安裝目錄中主要生存兩個DLL類庫,在這裏主要使用:InTheHand.Net.Personal.dll類庫進行操作,在操作過程中,主要使用到一下四個類:
 
1. BluetoothClient ——搜索並獲取周圍的藍牙設備
2. BluetoothListener——監聽並接收消息
4. BluetoothDeviceInfo——藍牙設備對象
 
經過仔細分析,封裝了一個類,接下來是該類的代碼:
using System;
using System.Collections.Generic;
using System.Text;
using InTheHand.Net.Sockets;
using System.IO;
using InTheHand.Net.Bluetooth;
using System.Threading;
using System.Collections;
using InTheHand.Net;
using System.Windows.Forms;
namespace FiveChessGame.Class
{
    #region 事件獲取消息機制
    public class AddChessEventArgs : EventArgs
    {
        public string message;//存放要顯示的內容
    }
    #endregion
    #region 類體
    public sealed class BlueTooth
    {
        #region 定義變量
        public BluetoothClient btc;//定義客戶對象
        public BluetoothListener listener;//實現監聽類;//實現監聽類
        public BluetoothRadio myRadio;//定義自己的藍牙設備
        public Hashtable hashTb; //存儲搜索到得用戶
        public string myRadioInfo;//儲存自己的設備信息
        public string data;//定義監聽到的數據
        public event EventHandler<AddChessEventArgs> OnAddChess;//定義事件獲取流中的數據
        public delegate void GetMessageDelegate(string mes);
        #endregion
        #region 構造並實例

        static BlueTooth _blue = new BlueTooth();
        public static BlueTooth GetObject
        {
            get { return _blue; }
        }
        BlueTooth()
        {
            btc = new BluetoothClient();
            listener = new BluetoothListener(BluetoothService.SerialPort);
            hashTb = new Hashtable();
            try
            {
                OpenBlueTooth();
                myRadioInfo = getMyRadio();
            }
            catch
            {
                MessageBox.Show("你的藍牙設備不存在,或者出現什麼異常!", "提示 ", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            }
        }
        #endregion
        #region 啓用監聽
        public void StartListh()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(StartService));
        }
        #endregion
        #region 打開藍牙
        /// <summary>/./
        /// 如果成功打開藍牙返回TURE,否則返回FALSE
        /// </summary>
        /// <returns></returns>
        public bool OpenBlueTooth()
        {
            try
            {
                myRadio = BluetoothRadio.PrimaryRadio;
                if (myRadio == null)
                {
                    return false;
                }
                else
                {
                    myRadio.Mode = RadioMode.Discoverable;
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        public string getMyRadio()
        {
            return myRadio.LocalAddress.ToString();
        }
        #endregion
        #region 搜索藍牙設備
        public bool searchUser()
        {
            BluetoothClient client = new BluetoothClient();//定義搜索到的藍牙設備對象
            BluetoothDeviceInfo[] devices = client.DiscoverDevices();
            hashTb.Clear();
            foreach (BluetoothDeviceInfo d in devices)
            {
                hashTb.Add(d.DeviceName, d);
            }
            return true;
        }
        #endregion
        #region 鏈接藍牙設備
        /// <summary>
        ///
        /// </summary>
        /// <param name="d">  設備信息,通過客戶端定義的hashtable表進行獲取</param>
        /// <returns></returns>
        public bool ConnectionUser(BluetoothDeviceInfo d)
        {
            try
            {
                //btc.SetPin(d.DeviceAddress, "0000");驗證連接密碼(雙方密碼設置一致才能正常連接)
                btc.Connect(d.DeviceAddress, BluetoothService.SerialPort);
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion
        #region 發送數據
        /// <summary>
        /// 發送成功返回true,否則返回false
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public void SendMes(object message)
        {
            try
            {
                Stream peerStream = btc.GetStream();// 獲取友機設備發送的信息
                byte[] tmp = Encoding.Default.GetBytes(message.ToString());
                peerStream.Write(tmp, 0, tmp.Length);
            }
            catch (Exception error)
            { MessageBox.Show(error.Message); }
        }
        #endregion
        #region 監聽數據
        public void StartService(object o)
        {
            listener.Start();
            BluetoothClient clientOther = listener.AcceptBluetoothClient();
            Stream peerStream = clientOther.GetStream();
            byte[] buffer = new byte[2000];
            while (true)
            {
                if (peerStream.CanRead)
                {
                    peerStream.Read(buffer, 0, 50);
                    data = Encoding.Default.GetString(buffer, 0, 50);
                    //將多餘的空格換成e
                    data = data.Replace('/0', 'e');
                    //如果第一個字符是e代表這客戶端程序已經退出
                    string tmp = data.Substring(0, 1);
                    if (tmp == "e")
                    {
                        peerStream.Close();
                        break;
                    }
                    if (data != "")
                    {
                        //將字符串中多餘的e刪除
                        data = data.Replace("e", "");
                        AddChessEventArgs arg = new AddChessEventArgs();
                        arg.message = data;
                        OnAddChess(this, arg);
                    }
                }
            }
        }
        #endregion
    }
    #endregion
}
 
   上面就是一些具體代碼,值得注意的是,在這裏爲什麼要添加一個AddChessEventArgs類呢?原因是我們是用事件機制來獲取監聽到的消息,當一旦有消息獲取,就發送給事件,再在事件中做相應的處理。
     這個類解決了上面所有的問題,這裏爲什麼要獲取本機的藍牙設備信息呢? 因爲兩臺藍牙設備是要進行信息配對的,當A手機連接到B手機後,B手機只能被動接受A手機發送過來的信息,並不能主動向A手機發送自己的信息,所以在A手機連接成功B手機後,同時向B手機發送自己的地址信息,然後B手再根據這個地址信息嘗試連接A手機,一旦連接成功,兩臺手機配對成功。這樣就可以進行信息交互了。
     還有,這裏類也是一個單例類,也就是在實例的時候,該類只能被實例化一次,不然就會出現數據混亂的問題。
     難題解決,接下來該進行細節處理了。
3. BluetoothRadio——獲取藍牙設備信息類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章