so what im actually trying to do is to comunicate with a DMX-Interface pluged to a PC/Host via an Xamarin Android App.
Allready got my Server running, works also with an console client i wrote first. So now I wrote the app,using the same Way as before, with a TCPClient and then writing the data via a stream.
Because I'm running the app in the emulator I use as IP 10.0.2.2 to connect, but I cannot establish a connection. The App crashes or I get a timeout exeption. Been trying and researching now for two days and now i'm desperate, so I attach my code here, hope anyone can help
Thanks, Johannes
App:
public class MainActivity : Activity
{
public Stream Stream;
TcpClient Client = null;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
//adding control elements from Resource.Layout.Main
Button at = FindViewById<Button>(Resource.Id.at);
Button enter = FindViewById<Button>(Resource.Id.enter);
Button thru = FindViewById<Button>(Resource.Id.thru);
Button all = FindViewById<Button>(Resource.Id.all);
Button one = FindViewById<Button>(Resource.Id.one);
Button two = FindViewById<Button>(Resource.Id.two);
Button three = FindViewById<Button>(Resource.Id.three);
Button four = FindViewById<Button>(Resource.Id.four);
Button five = FindViewById<Button>(Resource.Id.five);
Button six = FindViewById<Button>(Resource.Id.six);
Button seven = FindViewById<Button>(Resource.Id.seven);
Button eight = FindViewById<Button>(Resource.Id.eight);
Button nine = FindViewById<Button>(Resource.Id.nine);
Button zero = FindViewById<Button>(Resource.Id.zero);
Button comma = FindViewById<Button>(Resource.Id.comma);
Button connect = FindViewById<Button>(Resource.Id.connect);
Button clear = FindViewById<Button>(Resource.Id.clear);
at.Click += (o, e) =>
{
UpdateCmdLine("#");
};
clear.Click += (o, e) =>
{
FlushCmdLine();
};
enter.Click += (o, e) =>
{
TextView cmdLine = FindViewById<TextView>(Resource.Id.cmdLine);
ProcessData(cmdLine.Text);
FlushCmdLine();
};
thru.Click += (o, e) =>
{
UpdateCmdLine("/");
};
all.Click += (o, e) =>
{
UpdateCmdLine("#");
};
one.Click += (o, e) =>
{
UpdateCmdLine("1");
};
two.Click += (o, e) =>
{
UpdateCmdLine("2");
};
three.Click += (o, e) =>
{
UpdateCmdLine("3");
};
four.Click += (o, e) =>
{
UpdateCmdLine("4");
};
five.Click += (o, e) =>
{
UpdateCmdLine("5");
};
six.Click += (o, e) =>
{
UpdateCmdLine("6");
};
seven.Click += (o, e) =>
{
UpdateCmdLine("7");
};
eight.Click += (o, e) =>
{
UpdateCmdLine("8");
};
nine.Click += (o, e) =>
{
UpdateCmdLine("9");
};
zero.Click += (o, e) =>
{
UpdateCmdLine("0");
};
comma.Click += (o, e) =>
{
UpdateCmdLine(",");
};
connect.Click += (o, e) =>
{
try
{
TextView ip = FindViewById<TextView>(Resource.Id.ipField);
TextView port = FindViewById<TextView>(Resource.Id.portField);
TextView connectionStatus = FindViewById<TextView>(Resource.Id.connectedStatus);
Client = new TcpClient("10.0.2.2", 4711);
connectionStatus.Text = "Connected";
}
catch (System.Exception)
{
}
};
//implementing click functions
}
public void UpdateCmdLine(string update)
{
TextView cmdLine = FindViewById<TextView>(Resource.Id.cmdLine);
cmdLine.Text += update;
}
public void FlushCmdLine()
{
TextView cmdLine = FindViewById<TextView>(Resource.Id.cmdLine);
cmdLine.Text = "";
}
public int[] GetData(string channel, string value)
{
int[] data = new int[] {Int32.Parse(channel), Int32.Parse(value)};
return data;
}
public void SendData(int channel, int data)
{
if (Client.Connected)
{
Stream = Client.GetStream();
byte[] outgoingBytes = new byte[] {Convert.ToByte(channel),Convert.ToByte(data)};
Stream.Write(outgoingBytes,0,outgoingBytes.Length);
}
}
public void ProcessData(string cmdLine)
{
string[] divideStackedOps = cmdLine.Split(',');
foreach (string s in divideStackedOps)
{
if (s.Contains("/"))
{
string[] dividedThru = s.Split('/');
int channel1 = Int32.Parse(dividedThru[0]);
string[] dividedAt = dividedThru[1].Split('#');
int channel2 = Int32.Parse(dividedAt[0]);
int value = Int32.Parse(dividedAt[1]);
for (int e = channel2; e >= channel1; e--)
{
SendData(e, value);
}
}
else if (s.Contains("#"))
{
string[]dividedAll = s.Split('#');
int value = Int32.Parse(dividedAll[1]);
for (int e = 100; e > 0; e--)
{
SendData(e, value);
}
}
}
}
}
}
Server
public class DmxInterface
{
[DllImport("K8062D.dll")]
public static extern void StartDevice();
[DllImport("K8062D.dll")]
public static extern void SetData(int channel, int data);
[DllImport("K8062D.dll")]
public static extern void StopDevice();
[DllImport("K8062D.dll")]
public static extern void SetChannelCount(int count);
}
class Program
{
private static TcpListener Listener;
private static ArrayList Threads = new ArrayList();
public static Boolean ServerStopped;
public static void Main()
{
DmxInterface.StartDevice();
DmxInterface.SetChannelCount(10);
//Initialize Listener, start Listener
int port = 4711;
IPAddress ip = IPAddress.Parse("127.0.0.1");
Listener = new TcpListener(ip, port);
Listener.Start();
Console.WriteLine("Creating new listener on: "+ip+":"+port);
//Initialize MainServerThread, start MainServerThread
Console.WriteLine("Starting MainThread");
Thread mainThread = new Thread(Run);
mainThread.Start();
Console.WriteLine("Done");
while (!ServerStopped)
{
Console.WriteLine("Write 'stop' to stop Server...");
String cmd = "";
cmd = Console.ReadLine();
if (cmd.ToLower().Equals("stop"))
{
Console.WriteLine("stopping server");
ServerStopped = true;
}
else
{
Console.WriteLine("unknow command: " + cmd);
}
}
EndThreads(mainThread);
}
public static void EndThreads(Thread mainThread)
{
//stopping MainThread
mainThread.Abort();
Console.WriteLine("MainThread stopped");
//stopping all Threads
for (IEnumerator e = Threads.GetEnumerator(); e.MoveNext();)
{
//Getting next ServerThread
Console.WriteLine("Stopping the ServerThreads");
ServerThread serverThread = (ServerThread)e.Current;
//Stop it
serverThread.Stop = true;
while (serverThread.Running)
{
Thread.Sleep(1000);
}
}
//Stopping Listener
Listener.Stop();
Console.WriteLine("listener stopped");
Thread.Sleep(5000);
Console.Clear();
}
//opening a new ServerThread
public static void Run()
{
while (true)
{
Console.WriteLine("Listener waiting for connection wish");
//waiting for incoming connection wish
TcpClient client = Listener.AcceptTcpClient();
Threads.Add(new ServerThread(client));
}
}
}
class ServerThread
{
public bool Stop;
public bool Running;
private TcpClient client;
public ServerThread(TcpClient client)
{
this.client = client;
//starting new thread with run() function
Console.WriteLine("Starting new ServerThread");
new Thread(new ThreadStart(Run)).Start();
}
//threaded function
public void Run()
{
Stream stream = null;
Boolean gotstream = false;
Console.WriteLine("Reading incoming Data Stream");
Running = true;
while (!gotstream)
{
//making sure stream is not null to avoid exeption
if (client.GetStream() != null)
{
//getting stream, setting flag true
stream = client.GetStream();
gotstream = true;
}
}
Boolean loop = true;
byte[] incomingValues = new byte[] {255, 255};
Boolean gotData = false;
while (loop)
{
//checking if a remote host is still connected
if (client.Connected)
{
try
{
//reading Byte Array
stream.Read(incomingValues, 0, incomingValues.Length);
gotData = true;
}
catch (Exception e)
{
//catching exeptions
Console.WriteLine("Ooops, something wrent wrogn \n" + e);
loop = false;
}
if (gotData)
{
//converting bytes to int, sending DMX Values
int channel = Convert.ToInt32(incomingValues[0]);
int value = Convert.ToInt32(incomingValues[1]);
DmxInterface.SetData(channel, value);
Console.WriteLine("Received Data... \n Channel: " + channel + " Value: " + value);
}
}
else
{
//exiting loop if connection is lost
Console.WriteLine("connection lost");
Program.ServerStopped = true;
loop = false;
}
}
}
}
}
Related
I wrote a chat application in C# WinForms. But if I close the client form (while this form is connected to the server form) and reopen the client form and try to reconnect, the client doesn't connect to the server..
How can I reconnect the client to the server if the application is closed and reopened?
(sorry for bad english)
Server:
public frmServer()
{
InitializeComponent();
textBox_Hostname.Text = GetLocalIPAddress();
Configuration Programmkonfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
Port = Programmkonfiguration.AppSettings.Settings["Port"].Value;
textBox_Port.Text = Port;
toolStripStatusLabel_Serverstatus.Text = "deaktiviert";
toolStripStatusLabel_Serverstatus.ForeColor = Color.Red;
textBox_Output.Focus();
}
private string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
private void button_Send_Click(object sender, EventArgs e)
{
if (!(string.IsNullOrWhiteSpace(textBox_Output.Text)))
{
String s = "Server: " + textBox_Output.Text + Environment.NewLine;
textBox_Input.Text += s;
byte[] byteTime = Encoding.ASCII.GetBytes(s);
ns.Write(byteTime, 0, byteTime.Length);
textBox_Output.Clear();
}
}
public void DoWork()
{
byte[] bytes = new byte[1024];
while (true)
{
int bytesRead = ns.Read(bytes, 0, bytes.Length);
this.SetText(Encoding.ASCII.GetString(bytes, 0, bytesRead));
}
}
private void SetText(string text)
{
if (this.textBox_Input.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox_Input.Text = this.textBox_Input.Text + text;
}
}
private void button_Starten_Click(object sender, EventArgs e)
{
IPAddress hostname = IPAddress.Parse(textBox_Hostname.Text);
int portNum = Convert.ToInt32(textBox_Port.Text);
listener = new TcpListener(hostname, portNum);
listener.Start();
Task TCPListener = new Task(() => AcceptTCP());
TCPListener.Start();
textBox_Input.Text += "Server gestartet." + Environment.NewLine;
button_Starten.Enabled = false;
toolStripStatusLabel_Serverstatus.Text = "aktiviert";
toolStripStatusLabel_Serverstatus.ForeColor = Color.Green;
}
private void AcceptTCP()
{
client = listener.AcceptTcpClient();
ns = client.GetStream();
Task Work = new Task(() => DoWork());
Work.Start();
}
private void textBox_Output_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
button_Send_Click(sender, e);
e.Handled = true;
textBox_Output.Focus();
}
}
}
Client:
public frmClient()
{
InitializeComponent();
Configuration Programmkonfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
HostnameServer = Programmkonfiguration.AppSettings.Settings["HostnameServer"].Value;
Port = Programmkonfiguration.AppSettings.Settings["Port"].Value;
textBox_Hostname.Text = GetLocalIPAddress();
textBox_Port.Text = Port;
toolStripStatusLabel_Status.Text = " nicht verbunden";
toolStripStatusLabel_Status.ForeColor = Color.Red;
textBox_Output.Focus();
}
private string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(HostnameServer);
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
private void button_Senden_Click(object sender, EventArgs e)
{
if (!(string.IsNullOrWhiteSpace(textBox_Output.Text)))
{
String s = "Client: " + textBox_Output.Text + Environment.NewLine;
textBox_Input.Text += s;
byte[] byteTime = Encoding.ASCII.GetBytes(s);
ns.Write(byteTime, 0, byteTime.Length);
textBox_Output.Clear();
}
}
public void DoWork()
{
byte[] bytes = new byte[1024];
while (true)
{
if (ns.DataAvailable)
{
int bytesRead = ns.Read(bytes, 0, bytes.Length);
this.SetText(Encoding.ASCII.GetString(bytes, 0, bytesRead));
}
}
}
private void SetText(string text)
{
if (this.textBox_Input.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox_Input.Text = this.textBox_Input.Text + text;
}
}
private void button_Connect_Click(object sender, EventArgs e)
{
string hostName = textBox_Hostname.Text;
int portNum = Convert.ToInt32(textBox_Port.Text);
client = new TcpClient(hostName, portNum);
ns = client.GetStream();
Work = new Task(() => DoWork());
Work.Start();
textBox_Input.Text += "Verbindung hergestellt." + Environment.NewLine;
button_Connect.Enabled = false;
toolStripStatusLabel_Status.Text = "verbunden";
toolStripStatusLabel_Status.ForeColor = Color.Green;
}
private void textBox_Output_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
button_Senden_Click(sender, e);
e.Handled = true;
textBox_Output.Focus();
}
}
}
Each call to Accept on a listener socket accepts a single connection. At the moment, your server accepts a single connection request and then ignores the listener socket from that point onwards.
Normally, you'd want some form of "Accept loop" that continually calls Accept, sets up the server side resources for that connection and then loops back to call Accept again.
E.g. the trivial change is to do this:
private void AcceptTCP()
{
while(true)
{
client = listener.AcceptTcpClient();
ns = client.GetStream();
Task Work = new Task(() => DoWork());
Work.Start();
}
}
But now you really have to think about what happens to ns - what happens if/when you want a second client connected simultaneously? Having NetworkStream be a single shared instance variable within the server isn't going to scale well.
Normally, you'd want to create some form of simple class that represents each connection + your server specific information relating to that connection. E.g. it would contain the NetworkStream, the current "state" of this connection (if you have modes or states), possibly the buffers that were last passed to a Read call as/when you start going async with this work, etc.
I've got an intra-PC communication server / client set up to send and receive data from one program to another - in this case, a custom server that is listening to text commands and Unity3D.
For the most part, it works, however every once in awhile, it will drop packets, and Unity will not get them without multiple attempts. The packets seem to be sent but lost, as I do see the "Sent message" console log. The following is the code for the server and client:
SERVER:
class TCPGameServer
{
public event EventHandler Error;
public Action<Data> ADelegate;
TcpListener TCPListener;
TcpClient TCPClient;
Client ActiveClient;
NetworkStream networkStream;
StreamWriter returnWriter;
StreamReader streamReader;
Timer SystemTimer = new Timer();
Timer PingTimer = new Timer();
int Port = 8637;
public TCPGameServer()
{
TCPListener = new TcpListener(IPAddress.Loopback, Port);
SystemTimer.Elapsed += StreamTimer_Tick;
SystemTimer.AutoReset = true;
SystemTimer.Interval = 2000;
PingTimer.Elapsed += PingTimer_Tick;
PingTimer.AutoReset = true;
PingTimer.Interval = 30000;
}
public void OpenListener()
{
TCPListener.Start();
TCPListener.BeginAcceptTcpClient(AcceptTCPCallBack, null);
Console.WriteLine("Network Open.");
}
public void GameLogout()
{
SystemTimer.AutoReset = false;
SystemTimer.Stop();
PingTimer.AutoReset = false;
PingTimer.Stop();
ActiveClient = null;
returnWriter.Dispose();
streamReader.Dispose();
Console.WriteLine("The client has logged out successfully.");
}
private void AcceptTCPCallBack(IAsyncResult asyncResult)
{
TCPClient = null;
ActiveClient = null;
returnWriter = null;
streamReader = null;
try
{
TCPClient = TCPListener.EndAcceptTcpClient(asyncResult);
TCPListener.BeginAcceptTcpClient(AcceptTCPCallBack, null);
ActiveClient = new Client(TCPClient);
networkStream = ActiveClient.NetworkStream;
returnWriter = new StreamWriter(TCPClient.GetStream());
streamReader = new StreamReader(TCPClient.GetStream());
Console.WriteLine("Client Connected Successfully.");
Data Packet = new Data();
Packet.cmdCommand = Command.Login;
Packet.strName = "Server";
Packet.strMessage = "LOGGEDIN";
SendMessage(Packet);
SystemTimer.AutoReset = true;
SystemTimer.Enabled = true;
SystemTimer.Start();
Ping();
PingTimer.AutoReset = true;
PingTimer.Enabled = true;
PingTimer.Start();
} catch (Exception ex)
{
OnError(TCPListener, ex);
return;
}
}
private void StreamTimer_Tick(object source, System.Timers.ElapsedEventArgs e)
{
CheckStream();
}
private void PingTimer_Tick(object source, System.Timers.ElapsedEventArgs e)
{
Ping();
}
private void Ping()
{
if (TCPClient.Connected)
{
Data Packet = new Data();
Packet.cmdCommand = Command.Ping;
Packet.strName = "Server";
Packet.strMessage = "PING";
SendMessage(Packet);
}
}
public void CheckStream()
{
try
{
if (TCPClient.Available > 0 || streamReader.Peek() >= 0)
{
string PacketString = streamReader.ReadLine();
Data packet = JsonConvert.DeserializeObject<Data>(PacketString);
switch (packet.cmdCommand)
{
case Command.Logout:
GameLogout();
break;
case Command.Message:
if (ADelegate != null)
{
ADelegate(packet);
}
break;
case Command.Ping:
Console.WriteLine("PONG!");
break;
}
}
} catch (IOException e)
{
Console.WriteLine(e.Message);
} catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
}
}
public void SendMessage(Data packet)
{
if (ActiveClient != null)
{
string packetMessage = JsonConvert.SerializeObject(packet);
returnWriter.WriteLine(packetMessage);
returnWriter.Flush();
}
}
public void OnError(object sender, Exception ex)
{
EventHandler handler = Error;
if (handler != null)
{
ErrorEventArgs e = new ErrorEventArgs(ex);
handler(sender, e);
}
}
public void RegisterActionDelegate(Action<Data> RegisterDelegate)
{
ADelegate += RegisterDelegate;
}
public void UnRegisterActionDelegate(Action<Data> UnregisterDelegate)
{
ADelegate -= UnregisterDelegate;
}
}
CLIENT:
public class TCPNetworkClient
{
public Action<Data> PacketDelegate;
public TcpClient TCPClient;
int Port = 8637;
StreamReader streamReader;
StreamWriter streamWriter;
Timer StreamTimer = new Timer();
public bool LoggedIn = false;
public void Start()
{
if (LoggedIn == false)
{
TCPClient = null;
StreamTimer.AutoReset = true;
StreamTimer.Interval = 2000;
StreamTimer.Elapsed += StreamTimer_Tick;
try
{
TCPClient = new TcpClient("127.0.0.1", Port);
streamReader = new StreamReader(TCPClient.GetStream());
streamWriter = new StreamWriter(TCPClient.GetStream());
StreamTimer.Enabled = true;
StreamTimer.Start();
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
}
private void StreamTimer_Tick(System.Object source, System.Timers.ElapsedEventArgs e)
{
if (TCPClient.Available > 0 || streamReader.Peek() >= 0)
{
string PacketString = streamReader.ReadLine();
Data packet = JsonConvert.DeserializeObject<Data>(PacketString);
PacketDelegate(packet);
}
}
public void Logout()
{
Data Packet = new Data();
Packet.cmdCommand = Command.Logout;
Packet.strMessage = "LOGOUT";
Packet.strName = "Game";
SendMessage(Packet);
if (streamReader != null && streamWriter != null)
{
streamReader.Dispose();
streamWriter.Dispose();
TCPClient.Close();
TCPClient = null;
streamReader = null;
streamWriter = null;
}
StreamTimer.Stop();
}
public void SendMessage(Data packet)
{
string packetMessage = JsonConvert.SerializeObject(packet);
try
{
streamWriter.WriteLine(packetMessage);
streamWriter.Flush();
} catch (Exception e)
{
}
}
public void RegisterActionDelegate(Action<Data> RegisterDelegate)
{
PacketDelegate += RegisterDelegate;
}
public void UnRegisterActionDelegate(Action<Data> UnregisterDelegate)
{
PacketDelegate -= UnregisterDelegate;
}
}
I'm not really sure what's going on, or if there are any more additional checks that I need to add into the system. Note: It's TCP so that "when" this fully works, I can drop the client into other programs that I might write that may not fully rely or use Unity.
new TcpClient("127.0.0.1", Port) is not appropriate for the client. Just use TcpClient(). There is no need to specify IP and port, both of which will end up being wrong.
TCPClient.Available is almost always a bug. You seem to assume that TCP is packet based. You can't test whether a full message is incoming or not. TCP only offers a boundaryless stream of bytes. Therefore, this Available check does not tell you if a whole line is available. Also, there could be multiple lines. The correct way to read is to have a reading loop always running and simply reading lines without checking. Any line that arrives will be processed that way. No need for timers etc.
The server has the same problems.
Issue (2) might have caused the appearance of lost packets somehow. You need to fix this in any case.
My project is to connecting pc with mobile device using 32feet.net library.
Until Now, my solution is doing steps like:
Scanning for devices in area.
pairing with selected device .
request pairing with mobile device and when it's okay this error appear :
"A socket operation failed because the destination host was down" and I don't know why and how to overcome this problem. Any help with this problem will be appreciated.
And my solution is:
namespace Bluetooth
{
public partial class Form1 : Form
{
List<string> items;
public Form1()
{
items = new List<string>();
InitializeComponent();
}
private void Connect_Click(object sender, EventArgs e)
{
if(ServerStarted )
{
updateUI("Server Already Started");
return;
}
if(rbClient.Checked)
{
//ConnectAsClient();
StartScan();
}
else
{
ConnectAsServer();
}
}
private void StartScan()
{
listBox.DataSource = null;
listBox.Items.Clear();
items.Clear();
Thread bluethoothscanthread = new Thread(new ThreadStart(scan));
bluethoothscanthread.Start();
}
BluetoothDeviceInfo[] devices;
private void scan()
{
updateUI("Starting Scan ...");
BluetoothClient client = new BluetoothClient();
devices = client.DiscoverDevicesInRange();
updateUI("Scan Completed......");
updateUI(devices.Length.ToString() + "devices discovered");
foreach(BluetoothDeviceInfo d in devices)
{
items.Add(d.DeviceName);
}
UpdateDeviceList();
}
private void ConnectAsServer()
{
Thread BluethoothServerThread = new Thread(new ThreadStart(ServerConnectThread));
BluethoothServerThread.Start();
}
private void ConnectAsClient()
{
throw new NotImplementedException();
}
Guid mUUID = new Guid("00001101-0000-1000-8000-00805F9B34FB");
bool ServerStarted = false;
public void ServerConnectThread()
{
ServerStarted = true;
updateUI("Server Started , Waiting For Clients ");
BluetoothListener bluelistner = new BluetoothListener(mUUID);
bluelistner.Start();
BluetoothClient conn = bluelistner.AcceptBluetoothClient();
updateUI("Client has connected");
Stream mstream = conn.GetStream();
while(true)
{
// handle server connection
try
{
byte[] Received = new byte[1024];
mstream.Read(Received, 0, Received.Length);
updateUI("Received : " + Encoding.ASCII.GetString(Received));
byte[] Sent = Encoding.ASCII.GetBytes("Hello World ");
mstream.Write(Sent, 0, Sent.Length);
}
catch(IOException exception)
{
updateUI("Client has disconnected !!! ");
}
}
}
private void updateUI(string message)
{
Func<int> del = delegate ()
{
tbOutput.AppendText(message + System.Environment.NewLine);
return 0 ;
};
Invoke(del);
}
private void UpdateDeviceList()
{
Func<int> del = delegate ()
{
listBox.DataSource = items;
return 0;
};
Invoke(del);
}
BluetoothDeviceInfo deviceinfo;
private void listBox_DoubleClick(object sender, EventArgs e)
{
deviceinfo = devices.ElementAt(listBox.SelectedIndex);
updateUI(deviceinfo.DeviceName + "Was Selected , attempting connect");
if( pairDevice())
{
updateUI("Device Paired.....");
updateUI("Starting Connect Thread");
Thread bluethoothClientThread = new Thread(new ThreadStart(ClientconnectThread));
bluethoothClientThread.Start();
}
else
{
updateUI("Pair Failed");
}
}
private void ClientconnectThread()
{
BluetoothClient client = new BluetoothClient();
updateUI("Attempting Connect");
client.BeginConnect(deviceinfo.DeviceAddress, mUUID, this.BluetoothClientConnectCallback, client);
}
void BluetoothClientConnectCallback(IAsyncResult result)
{
BluetoothClient client = (BluetoothClient)result.AsyncState;
BluetoothEndPoint bep = new BluetoothEndPoint(deviceinfo.DeviceAddress, BluetoothService.AvctpProtocol);
BluetoothClient cli = new BluetoothClient();
client.Connect(bep); // the exception throw in this line //
Stream stream = cli.GetStream();
stream.ReadTimeout = 10000;
//Stream peerStream = cli.GetStream();
// client.Connect(BluetoothAddress.Parse(items(0)), mUUID);
//client.EndConnect(result);
//while(true)
//{
// while (!ready) ;
// stream.Write(message, 0, message.Length);
//}
//streaming(result);
if(result.IsCompleted)
{
// client.EndConnect(result);
// Stream stream = client.GetStream();
// stream.ReadTimeout = 1000;
updateUI("Ya rabbbbb");
//while (!ready) ;
//stream.Write(message, 0, message.Length);
}
}
void streaming (IAsyncResult result)
{
BluetoothListener listn = new BluetoothListener(mUUID);
listn.Start();
BluetoothClient conn = listn.AcceptBluetoothClient();
Stream peerstream = conn.GetStream();
bool rightconn = peerstream.CanRead;
if(rightconn)
{
updateUI("Now you can streaming");
}
else
{
updateUI("Not Yet");
}
}
string mypin = "1234";
private bool pairDevice()
{
if(!deviceinfo.Authenticated)
{
if (!BluetoothSecurity.PairRequest(deviceinfo.DeviceAddress, mypin))
{
return false;
}
}
return true;
}
bool ready = false;
byte[] message;
private void tbText_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar == 13)
{
message = Encoding.ASCII.GetBytes(tbText.Text);
ready = true;
tbText.Clear();
}
}
}
} // End of namespace
I think I followed same example with you and of course I encountered same problem.
Rest of my codes are same with yours until "private void ClientconnectThread()" function and here is mine;
private void ClientConnectThread()
{
BluetoothClient client = new BluetoothClient();
updateUI("attempting connect");
//client.BeginConnect(deviceInfo.DeviceAddress, mUUID, this.BluetoothClientConnectCallback, client);
BluetoothAddress addressSeleccionado = deviceInfo.DeviceAddress;
Guid mUUID = new Guid("00001101-0000-1000-8000-00805F9B34FB");
BluetoothEndPoint ep = new BluetoothEndPoint(addressSeleccionado, mUUID);
client.Connect(ep);
updateUI("connected");
Stream stream = client.GetStream();
while (true)
{
byte[] received = new byte[1024];
stream.Read(received, 0, received.Length);
updateUI("received: ");
for (int i = 0; i < 15; i++)
{
updateUI(received[i].ToString());
}
if (ready)
{
ready = false;
stream.Write(message, 0, message.Length);
}
}
}
With this code I can connect the remote device and implement basic send/receive data communication. In order to my search over internet, "if this code does not fit for you", you might think that 32feet is not compatible with your bluetooth driver. (by the way my PC's OS is 64bit Win7 and I use the internal BT device of my PC )
Best regards.
Specifically, I need to develop a Desktop app that pulls data from H7 Heart Rate Sensor in C# code.
I have searched everywhere and i cant find nothing to help me.
The closest i cam is with this video (https://www.youtube.com/watch?v=Jn05CU3mxzo&list=UUizfLH6Q2igGUyTWO1bH3YA) tutorial but still it didn't find my H7 Heart Rate Sensor.
namespace _123
{
public partial class Form1 : Form
{
List<string> items;
public Form1()
{
InitializeComponent();
items = new List<string>();
}
private void bGo_Click(object sender, EventArgs e)//button
{
if (serverStarted)
{
updateUI("server aleredy started");
return;
}
if (rbClient.Checked) {
startScan();
}
else{
connectAsServer();
}
}
private void startScan() {
listBox1.DataSource = null;
listBox1.Items.Clear();
items.Clear();
Thread bluetoothScanThread = new Thread(new ThreadStart(scan));
bluetoothScanThread.Start();
}
BluetoothDeviceInfo[] devices;
private void scan ()
{
updateUI("Starting scan...");
BluetoothClient client = new BluetoothClient();
devices = client.DiscoverDevicesInRange();
updateUI("Scan complet");
updateUI(devices.Length.ToString() + "devices discovered");
foreach (BluetoothDeviceInfo d in devices)
{
items.Add(d.DeviceName);
}
updateDeviceList();
}
private void connectAsServer()
{
Thread bluetoothServerTherad = new Thread(new ThreadStart(ServerConnectThread));
bluetoothServerTherad.Start();
}
private void connectAsClient()
{
}
Guid mUUID = new Guid("ECC037FD-72AE-AFC5-9213-CA785B3B5C63");
bool serverStarted = false;
private void ServerConnectThread()
{
//throw new NotImplementedException();
serverStarted = true;
updateUI("Server started, waiting for clients");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
BluetoothClient conn = blueListener.AcceptBluetoothClient();
updateUI("Client has connected");
Stream mStream = conn.GetStream();
while (true)
{
try
{
byte[] received = new byte[1024];
mStream.Read(received, 0, received.Length);
updateUI("Received: " + Encoding.ASCII.GetString(received));
byte[] sent = Encoding.ASCII.GetBytes("hello world");
mStream.Write(sent, 0, sent.Length);
}
catch (IOException exeption)
{
updateUI("Client has disconected!");
}
}
}
private void updateUI(string message)
{
Func<int> del = delegate()
{
tbOutput.AppendText(message + System.Environment.NewLine);
return 0;
};
Invoke(del);
}
private void updateDeviceList()
{
Func<int> del = delegate()
{
listBox1.DataSource = items;
return 0;
};
Invoke(del);
}
BluetoothDeviceInfo deviceInfo;
private void listBox1_DoubleClick(object sender, EventArgs e)
{
deviceInfo = devices.ElementAt(listBox1.SelectedIndex);
updateUI(deviceInfo.DeviceName + " was selected, attemting connect");
if (pairDevice())
{
updateUI("device paired..");
updateUI("starting conected thread");
Thread bluetoothClientThread = new Thread(new ThreadStart(ClientConnectThread));
bluetoothClientThread.Start();
}
else
{
updateUI("pair failed");
}
}
private void ClientConnectThread()
{
BluetoothClient client = new BluetoothClient();
updateUI("attepting connnection");
client.BeginConnect(deviceInfo.DeviceAddress, mUUID, this.BluetoothClientConnectCallback, client);
}
void BluetoothClientConnectCallback(IAsyncResult result)
{
BluetoothClient client = (BluetoothClient)result.AsyncState;
client.EndConnect(result);
Stream stream = client.GetStream();
stream.ReadTimeout = 1000;
while (true)
{
while (!ready) ;
stream.Write(message, 0, message.Length);
}
}
string myPin = "1234";
private bool pairDevice()
{
if (!deviceInfo.Authenticated)
{
if (!BluetoothSecurity.PairRequest(deviceInfo.DeviceAddress, myPin))
{
return false;
}
}
return true;
}
bool ready = false;
byte[] message;
private void tbText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
message = Encoding.ASCII.GetBytes(tbText.Text);
ready = true;
tbText.Clear();
}
}
}
}
This question is old now but here is my answer. So if you have Polar H7 and you are trying to get the Heart rate then I would recommend follow this Bluetooth Low Energy sample and just run the code it should work fine.
After you run this sample click on start enumerating and it will give you list of all the Bluetooth device .
Then find Polar H7 and click on it.
Go to step 2 and hit Connect and choose characteristic and service and you are done.
I have a problem that I can't resolve by myself.
I have an ObservableCollection of "product" with a "price" property.
Every second, the price of every products change. This is my server part.
I have a window, with some textbox, which bind on the price property.
In an other part, I have a client. The client needs to get the price of all products.
So, first, my client connect to my server (no problem here). it sends a message to server, server receives it.
My problem is here : the value of the price property change every second, but in my thread, I can't get the new values...
Here my code :
- Product :
private volatile float price;
public float Price
{
get { return price; }
set
{
price = value;
notifyPropertyChanged("Price");
}
}
public Product(int time)
{
timer = new Timer(time);
timer.Elapsed += timer_Elapsed;
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
this.Price++;
}
my server :
private ObservableCollection<product> listGroupProduct;
public MainWindow()
{
Thread thread;
InitializeComponent();
this.DataContext = this;
// Create the server
thread = new Thread(() => createServer(ref listGroupProduct));
thread.Start();
}
public static void createServer(ref ObservableCollection<Product> list)
{
string client = "";
try
{
IPAddress ipAdress = IPAddress.Parse("192.168.1.50");
TcpListener listener = new TcpListener(ipAdress, 1220);
listener.Start();
socket = listener.AcceptSocket();
// Receive client name
client = ReceiveMessage(100);
MessageBox.Show("New client connected : " + client);
// Send number of products
SendMessage(list.Count.ToString());
// Get articles request from a client
ReceiveMessage(8);
// Send all articles
while (true)
{
for (int i = 0; i < 3; i++)
{
if (articlesString != "")
articlesString += "|";
articlesString += list[i].Price + ";";
}
byte[] bytes = new byte[list.Count * 50];
bytes = System.Text.Encoding.ASCII.GetBytes(articlesString.ToCharArray());
socket.Send(bytes);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
private static void SendMessage(string p)
{
byte[] bytes = new byte[p.Length];
bytes = System.Text.Encoding.ASCII.GetBytes(p.ToCharArray());
socket.Send(bytes);
}
private static string ReceiveMessage(int p)
{
string tmp = "";
byte[] b = new byte[p];
int k = socket.Receive(b);
for (int i = 0; i < k; i++)
tmp += Convert.ToChar(b[i]);
return tmp;
}
My client :
private StreamSocket streamSocket;
public string Server = "192.168.1.89";
public int Port = 1220;
IInputStream inputStream;
IOutputStream outputStream;
public MainPage()
{
this.InitializeComponent();
CreateSocket();
}
void timer_Tick(object sender, object e)
{
SendMessage("articles");
toto.Text = "Message send : articles";
GetAllArticles();
}
private async void GetAllArticles()
{
toto.Text = await GetMessage(50);
toto.Text = "Waiting articles...";
toto.Text = await GetMessage(articlesNumber * 50));
}
private async Task CreateConnection()
{
SendMessage("tablet");
toto.Text = "message send : tablet";
articlesNumber = int.Parse(await GetMessage(1));
toto.Text = "Number articles : " + articlesNumber.ToString();
}
private async void CreateSocket()
{
DispatcherTimer timer = new DispatcherTimer();
streamSocket = new StreamSocket();
await streamSocket.ConnectAsync(new HostName(Server), Port.ToString());
inputStream = streamSocket.InputStream;
outputStream = streamSocket.OutputStream;
timer.Interval = new TimeSpan(0, 0, 1);
timer.Tick += timer_Tick;
// Envoi du nom et réception du nombre d'articles
await CreateConnection();
// Réception de tous les articles chaque secondes
SendMessage("tablet");
timer.Start();
}
private async void SendMessage(string message)
{
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(message, BinaryStringEncoding.Utf8);
await outputStream.WriteAsync(buffer);
}
private async Task<string> GetMessage(int size)
{
byte[] tmp = new byte[size];
IBuffer buffer1 = CryptographicBuffer.CreateFromByteArray(tmp);
toto.Text = "Waiting message... (size : " + size.ToString() + ")";
await inputStream.ReadAsync(buffer1, (uint)size, InputStreamOptions.None);
toto.Text = "Message received !";
return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, buffer1);
}
(By the way : "toto" is a textbox I use for debug :) )
Have you an idea why my client receive well the first value, but when, on my server side, the value change, my client continue to get the same value and not the new one ?
It looks like the server has infinite loop and keeps resending same data over and over again. CreateServer has the infinite loop immediately after the "Send all articles" comment.