Here is the error
NullReferenceException: Object reference not set to an instance of an object
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at <13e6546058e340ada820e34dce3b245e>:0)
Unity.Collections.NativeList`1[T].get_Length () (at Library/PackageCache/com.unity.collections#1.2.4/Unity.Collections/NativeList.cs:227)
Unity.Networking.Transport.NetworkDriver+Concurrent.BeginSend (Unity.Networking.Transport.NetworkPipeline pipe, Unity.Networking.Transport.NetworkConnection id, Unity.Networking.Transport.DataStreamWriter& writer, System.Int32 requiredPayloadSize) (at Library/PackageCache/com.unity.transport#1.1.0/Runtime/NetworkDriver.cs:177)
Unity.Networking.Transport.NetworkDriver.BeginSend (Unity.Networking.Transport.NetworkConnection id, Unity.Networking.Transport.DataStreamWriter& writer, System.Int32 requiredPayloadSize) (at Library/PackageCache/com.unity.transport#1.1.0/Runtime/NetworkDriver.cs:1210)
Server.SendToClient (Unity.Networking.Transport.NetworkConnection connection, NetMessage msg) (at Assets/Scripts/Net/Server.cs:196)
Chessboard.OnWelcomeServer (NetMessage msg, Unity.Networking.Transport.NetworkConnection cnn) (at Assets/Scripts/Chessboard.cs:774)
NetWelcome.ReceivedOnServer (Unity.Networking.Transport.NetworkConnection cnn) (at Assets/Scripts/Net/NetMessage/NetWelcome.cs:32)
NetUtility.OnData (Unity.Networking.Transport.DataStreamReader stream, Unity.Networking.Transport.NetworkConnection cnn, Server server) (at Assets/Scripts/Net/NetUtility.cs:32)
Server.UpdateMessagePump () (at Assets/Scripts/Net/Server.cs:133)
Server.Update () (at Assets/Scripts/Net/Server.cs:121)
Code:
using Unity.Collections;
using System;
using Unity.Networking.Transport;
using UnityEngine;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net;
public class Server : MonoBehaviour
{
public string GetLocalIpAddress()
{
UnicastIPAddressInformation mostSuitableIp = null;
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var network in networkInterfaces)
{
if (network.OperationalStatus != OperationalStatus.Up)
continue;
var properties = network.GetIPProperties();
if (properties.GatewayAddresses.Count == 0)
continue;
foreach (var address in properties.UnicastAddresses)
{
if (address.Address.AddressFamily != AddressFamily.InterNetwork)
continue;
if (IPAddress.IsLoopback(address.Address))
continue;
if (!address.IsDnsEligible)
{
if (mostSuitableIp == null)
mostSuitableIp = address;
continue;
}
// The best IP is the IP got from DHCP server
if (address.PrefixOrigin != PrefixOrigin.Dhcp)
{
if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
mostSuitableIp = address;
continue;
}
return address.Address.ToString();
}
}
return mostSuitableIp != null
? mostSuitableIp.Address.ToString()
: "";
}
#region Singeton implementation
public static Server Instance { set; get; }
private void Awake()
{
Instance = this;
}
#endregion
public NetworkDriver driver;
private NativeList<NetworkConnection> connections;
private bool isLocal = false;
private bool isActive = false;
private const float keepAliveTickRate = 20.0f;
private float lastKeepAlive;
public Action connectionDropped;
// Methods
public void Init(ushort port, bool localGame)
{
isLocal = localGame;
driver = NetworkDriver.Create();
NetworkEndPoint endPoint = NetworkEndPoint.Parse(GetLocalIpAddress(), port);
Debug.Log("TEST Local: " + endPoint.Address);
// endPoint.Port = port;
if (driver.Bind(endPoint) != 0)
{
Debug.Log("Unable to bind op port" + endPoint.Port);
}
else
{
driver.Listen();
Debug.Log("Currently listening on port" + endPoint.Port);
}
connections = new NativeList<NetworkConnection>(2, Allocator.Persistent);
isActive = true;
}
public void Shutdown()
{
if (isActive)
{
driver.Dispose();
connections.Dispose();
isActive = false;
}
}
public void OnDestroy()
{
Shutdown();
}
public void Update()
{
if (!isActive)
return;
KeepAlive();
driver.ScheduleUpdate().Complete();
CleanupConnections();
AcceptNewConnection();
UpdateMessagePump();
}
private void UpdateMessagePump()
{
DataStreamReader stream;
for (int i = 0; i < connections.Length; i++)
{
NetworkEvent.Type cmd;
while ((cmd = driver.PopEventForConnection(connections[i], out stream)) != NetworkEvent.Type.Empty)
{
if (cmd == NetworkEvent.Type.Data)
{
NetUtility.OnData(stream, connections[i], this);
}
else if (cmd == NetworkEvent.Type.Disconnect)
{
Debug.Log("Client disconnected from server");
connections[i] = default(NetworkConnection);
connectionDropped?.Invoke();
Shutdown(); // This is only if it is locah Host
}
}
}
}
// Server specific
private void KeepAlive()
{
if((Time.time - lastKeepAlive) > keepAliveTickRate)
{
lastKeepAlive = Time.time;
Broadcast(new NetKeepAlive());
}
}
private void CleanupConnections()
{
for (int i = 0; i < connections.Length; i++)
{
if (!connections[i].IsCreated)
{
connections.RemoveAtSwapBack(i);
--i;
}
}
}
private void AcceptNewConnection()
{
NetworkConnection c;
// Accept new connections
if (isLocal == true)
{
if (connections.Length == 0)
{
while ((c = driver.Accept()) != default(NetworkConnection))
{
connections.Add(c);
Debug.Log("New connection Added");
}
}
}
else if(isLocal == false)
{
if(connections.Length <= 1)
{
while ((c = driver.Accept()) != default(NetworkConnection))
{
connections.Add(c);
Debug.Log("New connection Added");
}
}
}
}
public void SendToClient(NetworkConnection connection, NetMessage msg)
{
DataStreamWriter writer;
driver.BeginSend(connection, out writer);
msg.Serialize(ref writer);
driver.EndSend(writer);
}
public void Broadcast(NetMessage msg)
{
for (int i = 0; i < connections.Length; i++)
if (connections[i].IsCreated)
{
// Debug.Log($"Sending {msg.Code} to : {connections[1].InternalId}");
SendToClient(connections[i], msg);
}
}
}
How do i fix it?
Related
Im using google play services cloud save. I found a tutorial about how to save, but for one thing like just for highscore. I want to save multiple playerprefs, for example I have 3 ability and every one of it is saving in a playerpref so I want to save them in to the cloud and I have gold to buy these abilitys and you can buy the gold with IAP so I want to save gold too in cloud but I have no idea how to save multiple playerprefs can you help me.
My playerprefs is like this
PlayerPrefs.SetInt("Revive", revive);
PlayerPrefs.SetInt("SlowTime", slowTime);
PlayerPrefs.SetInt("Immortal", immortal);
Im changing and saving the gold after IAP purchase
PlayerPrefs.SetInt("Gold", PlayerPrefs.GetInt("Gold") + 250);
This is the Cloud Save Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GooglePlayGames;
using UnityEngine.SocialPlatforms;
using GooglePlayGames.BasicApi;
using GooglePlayGames.BasicApi.SavedGame;
using System.Text;
using System;
public class PlayGamesController : MonoBehaviour
{
public static PlayGamesController Instance { set; get; }
const string Save_Name = "Save";
bool isSaving;
bool isCloudDataLoaded = false;
private void Start()
{
if (Instance == null)
{
DontDestroyOnLoad(gameObject);
Instance = this;
}
else
{
Destroy(gameObject);
}
if (!PlayerPrefs.HasKey(Save_Name))
PlayerPrefs.SetString(Save_Name, "0");
if (!PlayerPrefs.HasKey("IsFirstTime"))
PlayerPrefs.SetInt("IsFirstTime", 1);
LoadLocal();
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder().EnableSavedGames().Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.Activate();
SignIn();
}
private void SignIn()
{
Social.localUser.Authenticate((success) => {
LoadData();
});
}
public void AddScoreToLeaderboard(string leaderboardId, long score)
{
Social.ReportScore(score, leaderboardId, (bool success) => { });
}
public void OnAchievementClick()
{
if (Social.localUser.authenticated)
{
Social.ShowAchievementsUI();
}
if (!Social.localUser.authenticated)
{
SignIn();
}
}
public void OnLeaderboardClick()
{
if (Social.localUser.authenticated)
{
Social.ShowLeaderboardUI();
}
if (!Social.localUser.authenticated)
{
SignIn();
}
}
#region Saved Games
string GameDataToString()
{
return CloudVariables.highScore.ToString();
}
void StringToGameData(string cloudData, string localData)
{
if(PlayerPrefs.GetInt("IsFirstTime") == 1)
{
PlayerPrefs.SetInt("IsFirstTime", 0);
if (int.Parse(cloudData) > int.Parse(localData))
{
PlayerPrefs.SetString(Save_Name, cloudData);
}
}
else
{
if(int.Parse(localData) > int.Parse(cloudData))
{
CloudVariables.highScore = int.Parse(localData);
AddScoreToLeaderboard(GPGSIds.leaderboard_high_score, CloudVariables.highScore);
isCloudDataLoaded = true;
SaveData();
return;
}
}
CloudVariables.highScore = int.Parse(cloudData);
isCloudDataLoaded = true;
}
void StringToGameData(string localData)
{
CloudVariables.highScore = int.Parse(localData);
}
public void LoadData()
{
if (Social.localUser.authenticated)
{
isSaving = false;
((PlayGamesPlatform)Social.Active).SavedGame.OpenWithManualConflictResolution(Save_Name, DataSource.ReadCacheOrNetwork, true, ResolveConflict, OnSavedGameOpened);
}
else
{
LoadLocal();
}
}
private void LoadLocal()
{
StringToGameData(PlayerPrefs.GetString(Save_Name));
}
public void SaveData()
{
if (!isCloudDataLoaded)
{
SaveLocal();
return;
}
if (Social.localUser.authenticated)
{
isSaving = true;
((PlayGamesPlatform)Social.Active).SavedGame.OpenWithManualConflictResolution(Save_Name, DataSource.ReadCacheOrNetwork, true, ResolveConflict, OnSavedGameOpened);
}
else
{
SaveLocal();
}
}
private void SaveLocal()
{
PlayerPrefs.SetString(Save_Name, GameDataToString());
}
private void ResolveConflict(IConflictResolver resolver, ISavedGameMetadata original, byte[] originalData, ISavedGameMetadata unmerged, byte[] unmergedData)
{
if (originalData == null)
resolver.ChooseMetadata(unmerged);
else if (unmergedData == null)
resolver.ChooseMetadata(original);
else
{
string originalStr = Encoding.ASCII.GetString(originalData);
string unmergedStr = Encoding.ASCII.GetString(unmergedData);
int originalNum = int.Parse(originalStr);
int unmergedNum = int.Parse(unmergedStr);
if(originalNum > unmergedNum)
{
resolver.ChooseMetadata(original);
return;
}
else if (unmergedNum > originalNum)
{
resolver.ChooseMetadata(unmerged);
return;
}
resolver.ChooseMetadata(original);
}
}
private void OnSavedGameOpened(SavedGameRequestStatus status, ISavedGameMetadata game)
{
if(status == SavedGameRequestStatus.Success)
{
if (!isSaving)
LoadGame(game);
else
SaveGame(game);
}
else
{
if (!isSaving)
LoadLocal();
else
SaveLocal();
}
}
private void LoadGame(ISavedGameMetadata game)
{
((PlayGamesPlatform)Social.Active).SavedGame.ReadBinaryData(game, OnSavedGameDataRead);
}
private void SaveGame(ISavedGameMetadata game)
{
string stringToSave = GameDataToString();
PlayerPrefs.SetString(Save_Name, stringToSave);
byte[] dataToSave = Encoding.ASCII.GetBytes(stringToSave);
SavedGameMetadataUpdate update = new SavedGameMetadataUpdate.Builder().Build();
((PlayGamesPlatform)Social.Active).SavedGame.CommitUpdate(game, update, dataToSave, OnSavedGameDataWritten);
}
private void OnSavedGameDataRead(SavedGameRequestStatus status, byte[] savedData)
{
if(status == SavedGameRequestStatus.Success)
{
string cloudDataString;
if (savedData.Length == 0)
cloudDataString = "0";
else
cloudDataString = Encoding.ASCII.GetString(savedData);
string localDataString = PlayerPrefs.GetString(Save_Name);
StringToGameData(cloudDataString, localDataString);
}
}
private void OnSavedGameDataWritten(SavedGameRequestStatus status, ISavedGameMetadata game)
{
}
#endregion /Saved Games
}
I'm trying to create a TCP Client-Server connection, the client can connect to the server successfully, but I can't receive the data I'm sending from the server and I get this Error:
NullReferenceException: Object reference not set to an instance of an object ClientHandlePackets.HandleDataPackets (System.Byte[] data) (at Assets/Client/Scripts/ClientHanlePackets.cs:89) ClientHandlePackets.HandleData (System.Byte[] data) (at Assets/Client/Scripts/ClientHanlePackets.cs:61) ClientTCP.Update () (at Assets/Client/Scripts/ClientTCP.cs:31)
How can I Solve this?
c#
using System.Collections.Generic;
using UnityEngine;
public enum ServerPackets
{
S_INFORMATION = 1,
S_EXECUTEMETHODONCLIENT,
}
public class ClientHandlePackets : MonoBehaviour
{
public static Bytebuffer playerbuffer;
public delegate void Packet_(byte[] data);
private static Dictionary<long, Packet_> packets;
private static long pLength;
private void Awake()
{
initalizePackets();
}
private static void initalizePackets()
{
packets = new Dictionary<long, Packet_>();
packets.Add((long)ServerPackets.S_INFORMATION, PacketInformation);
}
public static void HandleData(byte[] data)
{
byte[] Buffer;
Buffer = (byte[])data.Clone();
if (playerbuffer == null) { playerbuffer = new Bytebuffer(); };
playerbuffer.WriteBytes(Buffer);
if (playerbuffer.Count() == 0)
{
playerbuffer.Clear();
return;
}
if (playerbuffer.Length() >= 8)
{
pLength = playerbuffer.ReadLong(false);
if (pLength <= 0)
{
playerbuffer.Clear();
return;
}
}
while (pLength > 0 & pLength <= playerbuffer.Length() - 8)
{
if (pLength <= playerbuffer.Length() - 8)
{
playerbuffer.ReadLong(); //REads out the packet identifier
data = playerbuffer.Readbytes((int)pLength); // Gets the full package length
HandleDataPackets(data);
}
pLength = 0;
if (playerbuffer.Length() >= 8)
{
pLength = playerbuffer.ReadLong(false);
if (pLength < 0)
{
playerbuffer.Clear();
return;
}
}
}
}
private static void HandleDataPackets(byte[] data)
{
long packetIdentifier;
Bytebuffer Buffer;
Packet_ packet;
Buffer = new Bytebuffer();
Buffer.WriteBytes(data);
packetIdentifier = Buffer.ReadLong();
Buffer.Dispose();
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
}
private static void PacketInformation(byte[] data)
{
Bytebuffer buffer = new Bytebuffer();
buffer.WriteBytes(data);
long packetIdentifier = buffer.ReadLong();
string msg1 = buffer.Readstring();
string msg2 = buffer.Readstring();
int Level = buffer.ReadInteger();
Debug.Log(msg1);
Debug.Log(msg2);
Debug.Log(Level);
}
}
using System;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.UI;
public class ClientTCP: MonoBehaviour
{
public Text info;
public static ClientTCP instance;
public TcpClient client;
public NetworkStream mystream;
private byte[] AsynchBuffer;
public bool IsConnected;
public byte[] Receivebyte;
public bool handleData = false;
private string IP_Adress= "127.0.0.1";
private int port=5555;
private void Awake()
{
instance = this;
}
private void Update()
{
if (handleData == true)
{
ClientHandlePackets.HandleData(Receivebyte);
handleData = false;
}
}
public void Connect()
{
Debug.Log("Trying to connect to the sever...");
client = new TcpClient();
client.ReceiveBufferSize = 4096;
client.SendBufferSize = 4096;
AsynchBuffer = new byte[8192];
try
{
client.BeginConnect(IP_Adress, port, new AsyncCallback(ConnectCallback), client);
}
catch
{
Debug.Log("unable to connect to the server");
}
}
private void ConnectCallback(IAsyncResult result)
{
try
{
client.EndConnect(result);
if (client.Connected == false)
{
return;
}
else
{
mystream = client.GetStream();
mystream.BeginRead(AsynchBuffer,0,8192,OnRecieveData,null);
IsConnected = true;
Debug.Log("You are connected to the server successfully!");
}
}
catch (Exception)
{
IsConnected = false;
return;
}
}
private void OnRecieveData(IAsyncResult result)
{
try
{
int packetlength = mystream.EndRead(result);
Receivebyte = new byte[packetlength];
Buffer.BlockCopy(AsynchBuffer, 0, Receivebyte, 0, packetlength);
if (packetlength == 0)
{
Debug.Log("disconnected");
Application.Quit();
return;
}
handleData = true;
mystream.BeginRead(AsynchBuffer, 0, 8192, OnRecieveData, null);
}
catch (Exception)
{
Debug.Log("disconnected");
Application.Quit();
return;
}
}
}
the problem is here:
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
to avoid this error you can use
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet?.Invoke(data);
}
But the problem is that i don't see where you fill your packets' dictionary with data in your code.
Can you show your ByteBuffer class?
I build a middle ware server.
I have 5(or 6) clients(different computer/IP address), and every client can have up to 6 connection -> max 36 connection to the server.
It is better to use only 1 port for all (e.g. 9000) or one different port for every client(e.g. 9000-9005) ?
I write me a simple test server(see code).
It worked like expected but maybe there is some room for optimization.
Thanks
My TCP server
public class TCPServerMulti : IDisposable
{
private static TcpListener _tcpListener;
private string _ipAdress = "";
private int _port = 9050;
private readonly Thread _listener;
private readonly bool _running;
private int cc = 0; //Test Counter
public string IPAdress
{
get { return _ipAdress; }
set { _ipAdress = value; }
}
public TCPServerMulti(int port)
{
if(port>0)
_port = port;
_running = true;
string sHostName = Dns.GetHostName();
IPAdress = "";
//Only use the first address -> need to change
IPAddress[] localAddress = Dns.GetHostAddresses(sHostName);
foreach (IPAddress ipAddress in localAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
_tcpListener = new TcpListener(ipAddress, _port);
IPAdress = ipAddress.ToString();
break;
}
}
if (IPAdress == "")
{
Console.Writeline("TCP Error");
return;
}
_tcpListener.Start();
_listener = new Thread(Listen) { IsBackground = true };
_listener.Start();
}
public TCPServerMulti():this(-1)
{}
//listening for clients
public void Listen()
{
try
{
while(_running)
{
cc++;
//create a own client object for every connection
TCPClientData cd = new TCPClientData(this, ""+cc, _tcpListener.AcceptTcpClient());
cd.StartClient();
if (ClientConnected != null) ClientConnected("Connected: " + cc);
}
_tcpListener.Stop();
}
catch (Exception)
{
}
}
public void Dispose()
{
_listener.Abort();
_tcpListener.Stop();
}
//Handle for Mainthread
internal void ReceiveClient(TCPClientData sender, string msg)
{
if (ReceiveMsg != null)
ReceiveMsg(sender, msg);
}
public delegate void ReceiveEventHandler(TCPClientData sender, string msg);
public event ReceiveEventHandler ReceiveMsg;
public delegate void ConnectedEventHandler(string msg);
public event ConnectedEventHandler ClientConnected;
}
Clientdata object
public class TCPClientData : IDisposable
{
private TCPServerMulti _master;
private byte[] _data;
private NetworkStream _networkStream;
private int _received;
private TcpClient _tcpClient;
private Thread _worker;
private bool _wrunning;
private string _id;
public TCPClientData(TCPServerMulti master,string id,TcpClient client)
{
_data = new byte[1024];
_master = master;
_id = id;
_tcpClient = client;
}
public string ID
{
get { return _id; }
}
private string ByteArrayToString(byte[] arr)
{
UTF8Encoding enc = new UTF8Encoding();
return enc.GetString(arr);
}
private byte[] StringToByteArray(string data)
{
UTF8Encoding enc = new UTF8Encoding();
return enc.GetBytes(data);
}
// Reading Data
private void Worker()
{
try
{
while (_wrunning)
{
if (_networkStream.DataAvailable)
{
_received = _networkStream.Read(_data, 0, _data.Length);
string s = ByteArrayToString(_data);
_master.ReceiveClient(this, s.Substring(0, _received));
}
else
{
Thread.Sleep(20);
}
}
_networkStream.Close();
_tcpClient.Close();
}
catch (Exception)
{ }
}
public void Dispose()
{
_worker.Abort();
_networkStream.Close();
_tcpClient.Close();
}
public void StartClient()
{
_networkStream = _tcpClient.GetStream();
_networkStream.ReadTimeout = 200;
_wrunning = true;
_worker = new Thread(Worker) { IsBackground = true };
_worker.Start();
}
public void StopClient()
{
_wrunning = false;
Thread.Sleep(700);
}
//Sending Data
public void WriteData(string msg)
{
byte[] b = StringToByteArray(msg);
_networkStream.Write(b,0,b.Length);
_networkStream.Flush();
}
}
Main Thread
static void Main(string[] args)
{
//Create Server
TCPServerPlugin.TCPServerMulti server=new TCPServerMulti(12345);
server.ClientConnected += Server_ClientConnected;
server.ReceiveMsg += Server_ReceiveMsg;
while (true)
{
}
}
//Callbacks
private static void Server_ClientConnected(string msg)
{
Console.WriteLine(msg);
}
private static void Server_ReceiveMsg(TCPClientData sender, string msg)
{
Console.WriteLine(string.Format("Sender: {0} -> MSG:{1}",sender.ID,msg));
if (msg == "!!X")
{
sender.Dispose();
sender = null;
}
else if(msg=="DATE")
sender.WriteData(DateTime.Now.ToLongDateString());
else if(msg=="TIME")
sender.WriteData(DateTime.Now.ToShortTimeString());
}
In Unity3d Webgl I download and write big file (about 100 mb and more) to cache (indexeddb).
I downloaded file with UnityWebRequest and write file in downloadHandler.
Sometimes after call filestream.Write() or filestream.Flush() Chrome will crash.
Exception not available, only crash tab of chrome.
Crash happens abount in 50 percent of dowloads.
public class Downloader : MonoBehaviour
{
public IEnumerator DownloadFileCoroutine(string url, string filePath, string clientName, int fileId, Action<int> downloadedCallback)
{
var currentWebRequest = UnityWebRequest.Get(url);
currentWebRequest.downloadHandler = new ToFileDownloadHandler(new byte[64 * 1024], filePath);
var downloadHendler = (currentWebRequest.downloadHandler as ToFileDownloadHandler);
currentWebRequest.Send();
while (!currentWebRequest.isDone && !currentWebRequest.isNetworkError && !currentWebRequest.isHttpError)
{
if (currentWebRequest.isNetworkError)
{
yield break;
}
}
if (currentWebRequest.isNetworkError)
{
downloadHendler.Cancel();
}
else
{
/// suceess
}
}
public class ToFileDownloadHandler : DownloadHandlerScript
{
private int _expected = -1;
private long _received = 0;
private readonly string _filepath;
private readonly FileStream _fileStream = null;
private bool _canceled = false;
public ToFileDownloadHandler(byte[] buffer, string filepath) : base(buffer)
{
CreateDir();
_filepath = filepath;
_fileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write);
}
protected override byte[] GetData() { return null; }
protected override bool ReceiveData(byte[] data, int dataLength)
{
if (data == null || data.Length < 1)
{
return false;
}
_received += dataLength;
if (!_canceled)
{
_fileStream.Write(data, 0, dataLength);
_fileStream.Flush();
}
return true;
}
protected override float GetProgress()
{
if (_expected < 0) return 0;
return (float)_received / _expected;
}
protected override void CompleteContent()
{
_fileStream.Close();
_isComplete = true;
}
protected override void ReceiveContentLength(int contentLength)
{
_expected = contentLength;
}
public void Cancel()
{
if (_canceled) return;
_canceled = true;
if (_fileStream != null)
{
_fileStream.Close();
}
File.Delete(_filepath);
}
private void CreateDir()
{
cachePath = Application.persistentDataPath;
if (!Directory.Exists(cachePath))
{
Directory.CreateDirectory(cachePath);
}
}
}
}
I am trying to use Symbol.WPAN.Bluetooth that comes with the EMDK for Symbol devices.
Does anyone happen to have a working example that transfers data?
Symbol's example just pairs the devices. (They apparently think that transfering data is not really needed in a Personal Area network example.)
Anyway, I know this is a long shot, but if anyone has gotten this to work I would love to see some code.
This is what I have tried. I have one device press button1 and another device press button2. The read value is always a zero length byte array.
using System.Text;
using System.Windows.Forms;
using Symbol.WPAN;
using Symbol.WPAN.Bluetooth;
namespace SmartDeviceProject1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Bluetooth bluetooth = new Bluetooth();
if (bluetooth.IsEnabled != true)
{
bluetooth.Enable();
bluetooth.RadioMode = BTH_RADIO_MODE.BTH_DISCOVERABLE_AND_CONNECTABLE;
}
RemoteDevice connectedDevice = null;
foreach (RemoteDevice remoteDevice in MakeEnumerable(bluetooth.RemoteDevices))
{
if ((remoteDevice.Name == "WM_Dan") && (remoteDevice.IsPaired == false))
{
remoteDevice.Pair();
connectedDevice = remoteDevice;
}
}
string test;
test = "Testing this out";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] encTest = encoding.GetBytes(test);
if (connectedDevice != null)
{
connectedDevice.WriteTimeout = 20000;
connectedDevice.Write(encTest);
}
}
public static IEnumerable<RemoteDevice> MakeEnumerable(RemoteDevices devices)
{
for (var i = 0; i < devices.Length; i++)
{
yield return devices[i];
}
}
private void button2_Click(object sender, EventArgs e)
{
Bluetooth bluetooth = new Bluetooth();
if (bluetooth.IsEnabled != true)
{
bluetooth.Enable();
bluetooth.RadioMode = BTH_RADIO_MODE.BTH_DISCOVERABLE_AND_CONNECTABLE;
}
RemoteDevice connectedDevice = null;
foreach (RemoteDevice remoteDevice in MakeEnumerable(bluetooth.RemoteDevices))
{
if ((remoteDevice.Name == "WM_Dan2") && (remoteDevice.IsPaired == false))
{
remoteDevice.Pair();
connectedDevice = remoteDevice;
}
}
string test;
test = "Testing this out";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] encTest = encoding.GetBytes(test);
byte[] encTest2;
string test2;
if (connectedDevice != null)
{
connectedDevice.ReadTimeout = 20000;
encTest2 = connectedDevice.Read(encTest.Length);
test2 = encoding.GetString(encTest2, 0, encTest2.Length);
MessageBox.Show(test2);
}
}
}
}
I gave up on using the built in com port connection and opened a SerialPort object on the connection.
SerialPort sp = new SerialPort();
sp.PortName = "COM" + connectedDevice.LocalComPort.ToString();
sp.BaudRate = 9600;
sp.DataBits = 8;
sp.Parity = Parity.None;
sp.StopBits = StopBits.One;
sp.Open();
sp.Open();
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
sp.ErrorReceived += new SerialErrorReceivedEventHandler(sp_ErrorReceived);
sp.WriteLine(textBoxSend.Text);
I also found that even though their docs said that LocalComPort was auto assigned, this was not always the truth. It was best to use their BTExplorer to set it first.
As well, there OpenComPort would work in situations where is should not -- using Reflector it is pretty obviously wrong. There are checking the return of ::CreateFile("COM" + port...) against 0 instead of -1 (INVALID_HANDLE_VALUE)
I don't know if this can ever help anyone, but here is an old piece of code that I wrote a few years back.
You'll have to clean it up so that it works for your application. My app had a TextBox control that it read from and logged errors to a Global class. Change that to work with what you have, and it should basically be good.
static class Scanner {
const string _CODEFILE = "Scanner.cs - Scanner::";
static int _baud = 9600;
static int _bits = 8;
static string _dataIn = null;
static string _port = "COM1";
static Parity _parity = Parity.None;
static StopBits _stop = StopBits.One;
static SerialPort _com1 = null;
static TextBox _textbox = null;
public enum ControlType { None, BadgeID, PartNumber, SerialNumber, WorkOrder };
static ControlType _control;
public static bool Available { get { return ((_com1 != null) && (_com1.IsOpen)); } }
public static bool Close {
get {
if (_com1 == null) return true;
try {
if (_com1.IsOpen) {
_com1.Close();
}
return (!_com1.IsOpen);
} catch { }
return false;
}
}
public static string Open() {
const string na = "Not Available";
if (_com1 == null) {
string reset = Reset();
if (!String.IsNullOrEmpty(reset)) return reset;
}
try {
_com1.Open();
return (_com1.IsOpen) ? null : na;
} catch (Exception err) {
return err.Message;
}
}
static void ProcessData(string incoming) {
_dataIn += incoming;
if ((_control != ControlType.None) && (_textbox != null)) {
bool ok = false;
string testData = _dataIn.Trim();
switch (_control) {
case ControlType.BadgeID:
if (testData.Length == 6) {
if (testData != BarCode.LOGOFF) {
Regex pattern = new Regex(#"[0-9]{6}");
ok = (pattern.Matches(testData).Count == 1);
} else {
ok = true;
}
}
break;
case ControlType.PartNumber:
if (testData.Length == 7) {
Regex pattern = new Regex(#"[BCX][P057][0-9]{5}");
ok = (pattern.Matches(testData).Count == 1);
}
break;
case ControlType.SerialNumber:
if (testData.Length == 15) {
Regex pattern = new Regex(#"[BCX][P057][0-9]{5} [0-9]{4} [0-9]{2}");
ok = (pattern.Matches(testData).Count == 1);
}
break;
case ControlType.WorkOrder:
if (testData.Length == 6) {
Regex pattern = new Regex(#"[0-9]{6}");
ok = (pattern.Matches(testData).Count == 1);
}
break;
}
if (ok) {
_textbox.Text = testData;
_textbox.ScrollToCaret();
_dataIn = null;
}
}
}
static string Reset() {
if (_com1 != null) {
try {
if (_com1.IsOpen) {
_com1.DiscardInBuffer();
_com1.Close();
}
} catch (Exception err) {
return err.Message;
}
Global.Dispose(_com1);
_com1 = null;
}
try {
_com1 = new SerialPort(_port, _baud, _parity, _bits, _stop);
_com1.DataReceived += new SerialDataReceivedEventHandler(Serial_DataReceived);
_com1.Open();
} catch (Exception err) {
return err.Message;
}
return null;
}
public static void ScanSource(ref TextBox objTextBox, ControlType objType) {
_textbox = objTextBox;
_control = objType;
_dataIn = null;
}
static void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e) {
ProcessData(_com1.ReadExisting());
}
public static void Settings(string ComPort, int BaudRate, Parity ParityValue, int Bits, StopBits StopBit) {
_port = ComPort;
_baud = BaudRate;
_parity = ParityValue;
_bits = Bits;
_stop = StopBit;
}
/// <summary>
/// Closes the COM Port
/// COM Port routines are ready to add as soon as I am
/// </summary>
static bool ComPortClose {
get {
if (_com1 == null) ComPortReset();
return ((_com1 == null) ? true : _com1.IsOpen ? false : true);
}
set {
if (_com1 == null) ComPortReset();
else if (_com1.IsOpen) {
_com1.DiscardInBuffer();
_com1.Close();
}
}
}
/// <summary>
/// Opens the COM Port
/// </summary>
static bool ComPortOpen {
get {
if (_com1 == null) ComPortReset();
return (_com1 == null) ? false : _com1.IsOpen;
}
set {
if (_com1 == null) ComPortReset();
if ((_com1 != null) && (!_com1.IsOpen)) _com1.Open();
}
}
/// <summary>
/// Initialized the Serial Port on COM1
/// </summary>
static void ComPortReset() {
if ((_com1 != null) && (_com1.IsOpen)) {
_com1.Close();
_com1 = null;
}
try {
_com1 = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
} catch (IOException err) {
Global.LogError(_CODEFILE + "ComPortReset", err);
}
}
}