⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bluetoothlistener.cs

📁 蓝牙传输控件,用于蓝牙文件上传和下载。芯片只要选用crs
💻 CS
字号:
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using bluetoothX;

namespace bluetoothX
{
	public class BluetoothListener
	{
	        private bool active = false;
		private BluetoothEndPoint serverEP;
	
	
		private int serviceHandle;
	        private ServiceRecord serviceRecord;
		private int channelOffset;
	        private ServiceClass codService;
	
		#region Constructor
	
	        public BluetoothListener(Guid service)
	        {
	            this.serverEP = new BluetoothEndPoint(BluetoothAddress.None, service);
	            serverSocket = new Socket(AddressFamily32.Bluetooth, SocketType.Stream, BluetoothProtocolType.RFComm);
	        }
	
	        public BluetoothListener(BluetoothAddress localaddr, Guid service)
	        {
	            if (localaddr == null) {
	                throw new ArgumentNullException("localaddr");
	            }
	            if (service == Guid.Empty) {
	                throw new ArgumentNullException("service");
	            }
	
	            this.serverEP = new BluetoothEndPoint(localaddr, service);
	            serverSocket = new Socket(AddressFamily32.Bluetooth, SocketType.Stream, BluetoothProtocolType.RFComm);
	        }
	
	        public BluetoothListener(BluetoothEndPoint localEP)
		{
	            if (localEP == null)
	            {
	                throw new ArgumentNullException("localEP");
	            }
	
	            this.serverEP = localEP;
	            serverSocket = new Socket(AddressFamily32.Bluetooth, SocketType.Stream, BluetoothProtocolType.RFComm);
		}
	
		public BluetoothListener(Guid service, byte[] sdpRecord, int channelOffset)
	            : this(service)
		{
	            serviceRecord = new ServiceRecord(sdpRecord);
				this.channelOffset = channelOffset;
		}
	
	        public BluetoothListener(BluetoothAddress localaddr, Guid service, byte[] sdpRecord, int channelOffset)
	            : this(localaddr, service)
	        {
	            serviceRecord = new ServiceRecord(sdpRecord);
	            this.channelOffset = channelOffset;
	        }
	
	        public BluetoothListener(BluetoothEndPoint localEP, byte[] sdpRecord, int channelOffset)
	            : this(localEP)
	        {
	            serviceRecord = new ServiceRecord(sdpRecord);
	            this.channelOffset = channelOffset;
	        }
	        #endregion
	
	        #region Local EndPoint
	
		public BluetoothEndPoint LocalEndPoint
		{
			get
			{
	        if (!active)
	        {
	            return serverEP;
	        }
	        return (BluetoothEndPoint)serverSocket.LocalEndPoint;
	
			}
		}
		#endregion
	
	        #region Service Class
	        public ServiceClass ServiceClass
	        {
	            get
	            {
	                return codService;
	            }
	            set
	            {
	                codService = value;
	            }
	        }
	        #endregion
	
	        #region Server
	
	        private Socket serverSocket;
		public Socket Server
		{
			get
			{
				return serverSocket;
			}
		}
		#endregion
	
		#region Start
        public void Start()
        {
            this.Start(int.MaxValue);
        }
	
	    public void Start(int backlog)
		{
            if ((backlog > int.MaxValue) || (backlog < 0))
            {
                throw new ArgumentOutOfRangeException("backlog");
            }
            if (serverSocket == null)
            {
                throw new InvalidOperationException("The socket handle is not valid.");
            }
            if (!active)
            {
                serverSocket.Bind(serverEP);

                //if we have a raw SDP record use that, otherwise we build a basic one
                if (serviceRecord == null)
                {
                    SdpRecordTemp srt = new SdpRecordTemp();
                    srt.Service = HostToNetworkOrder(this.serverEP.Service);
                    srt.Channel = (byte)((BluetoothEndPoint)serverSocket.LocalEndPoint).Port;
                    serviceRecord = new ServiceRecord(srt.ToByteArray());
                }
                else
                {
                    serviceRecord.ToByteArray()[channelOffset] = (byte)((BluetoothEndPoint)serverSocket.LocalEndPoint).Port;
                }

                serviceHandle = SetService(serviceRecord.ToByteArray(), codService);

                serverSocket.Listen(backlog);
                active = true;
            }
		}
		#endregion
	
		#region Stop
		/// <summary>
		/// Stops the socket from monitoring connections.
		/// </summary>
		public void Stop()
		{
			if(serverSocket!=null)
			{
				//remove service registration
				if(serviceHandle != 0)
				{
					RemoveService(serviceHandle, this.ServiceRecord.ToByteArray());
					serviceHandle = 0;
				}
	        		serverSocket.Close();
	        		serverSocket = null;
			}
	
	            active = false;
	            serverSocket = new Socket(AddressFamily32.Bluetooth, SocketType.Stream, BluetoothProtocolType.RFComm);
		}
		#endregion
	
		#region Accept
	
	        #region Async Socket
		public IAsyncResult BeginAcceptSocket(AsyncCallback callback, object state)
		{
	            if (!active)
	            {
	                throw new InvalidOperationException("Not listening. You must call the Start() method before calling this method.");
	            }
	            return serverSocket.BeginAccept(callback, state);
		}
	
		public Socket EndAcceptSocket(IAsyncResult asyncResult)
		{
			if (asyncResult == null)
			{
				throw new ArgumentNullException("asyncResult");
			}
			return serverSocket.EndAccept(asyncResult);
	        }
	        #endregion
	
	        #region Async Client
		public IAsyncResult BeginAcceptBluetoothClient(AsyncCallback callback, object state)
		{
	            if (!active)
	            {
	                throw new InvalidOperationException("Not listening. You must call the Start() method before calling this method.");
	            }
	
				return serverSocket.BeginAccept(callback, state);
		}
	
		public BluetoothClient EndAcceptBluetoothClient(IAsyncResult asyncResult)
		{
			if (asyncResult == null)
			{
				throw new ArgumentNullException("asyncResult");
			}
	
	            Socket s = serverSocket.EndAccept(asyncResult);
	            return new BluetoothClient(s);
	        }
	        #endregion
	
		public Socket AcceptSocket()
		{
	            if (!active)
	            {
	                throw new InvalidOperationException("Not listening. You must call the Start() method before calling this method.");
	            }
	
			return serverSocket.Accept();
		}
	
		public BluetoothClient AcceptBluetoothClient()
		{
	    		Socket s = AcceptSocket();
			return new BluetoothClient(s);
		}
		#endregion
	
		#region Pending
		public bool Pending()
		{
	            if (!active)
	            {
	                throw new InvalidOperationException("Not listening. You must call the Start() method before calling this method.");
	            }
	
				return serverSocket.Poll(0, SelectMode.SelectRead);
		}
		#endregion
	
	        #region Service Record
	        public ServiceRecord ServiceRecord
	        {
	            get
	            {
	                return this.serviceRecord;
	            }
	        }
	        #endregion
	
	        #region Service
	        private static void RemoveService(int handle, byte[] sdpRecord)
		{
	            BTHNS_SETBLOB blob = new BTHNS_SETBLOB(sdpRecord);
	            blob.Handle = handle;
	
	            WSAQUERYSET qs = new WSAQUERYSET();
	            qs.dwSize = 60;
	            qs.dwNameSpace = 16;
	
	            GCHandle hBlob = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned);
	
	            BLOB b = new BLOB(blob.Length, hBlob.AddrOfPinnedObject());
	
	            GCHandle hb = GCHandle.Alloc(b, GCHandleType.Pinned);
	
	            qs.lpBlob = hb.AddrOfPinnedObject();
	
	            try
	            {
	                int hresult = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_DELETE, 0);
	                BluetoothClient.ThrowSocketExceptionForHR(hresult);
	            }
	            finally
	            {
	                hb.Free();
	                hBlob.Free();
	            }            
		}
	
		private static int SetService(byte[] sdpRecord, ServiceClass cod)
		{
	            BTHNS_SETBLOB blob = new BTHNS_SETBLOB(sdpRecord);
	
	            blob.CodService = (uint)cod;
	
	            WSAQUERYSET qs = new WSAQUERYSET();
	            qs.dwSize = 60;
	            qs.dwNameSpace = 16;
	            GCHandle hBlob = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned);
	
	            BLOB b = new BLOB(blob.Length, hBlob.AddrOfPinnedObject());
	
	            GCHandle hb = GCHandle.Alloc(b, GCHandleType.Pinned);
	
	            qs.lpBlob = hb.AddrOfPinnedObject();
	
	            try
	            {
	                int hresult = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_REGISTER, 0);
	                BluetoothClient.ThrowSocketExceptionForHR(hresult);
	            }
	            finally
	            {
	                hb.Free();
	                hBlob.Free();
	            }
	            
			return blob.Handle;
		}
		#endregion
	
		#region Host To Network Order
		internal static Guid HostToNetworkOrder(Guid hostGuid)
		{
			byte[] guidBytes = hostGuid.ToByteArray();
			
			BitConverter.GetBytes(IPAddress.HostToNetworkOrder(BitConverter.ToInt32(guidBytes, 0))).CopyTo(guidBytes, 0);
			BitConverter.GetBytes(IPAddress.HostToNetworkOrder(BitConverter.ToInt16(guidBytes, 4))).CopyTo(guidBytes, 4);
			BitConverter.GetBytes(IPAddress.HostToNetworkOrder(BitConverter.ToInt16(guidBytes, 6))).CopyTo(guidBytes, 6);
			
			return new Guid(guidBytes);
		}
		#endregion

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -