Client Dissconnect or down - c#

I have 2 Application in a visual studio Windows Forms App(.Net Framework 4) The names of my two programs are:
IpServer
IpClient
My problem is that I do not know what to do that when the IpClient Application closes or stops or the IpServer Application shows a message in messagebox.show("Client Is dissconnect")
IpServer Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace IpServer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpListener tcplist;
Socket s;
private void init()
{
IPAddress ip = IPAddress.Parse("127.0.0.1");
tcplist = new TcpListener(ip,5050);
tcplist.Start();
while (true)
{
s = tcplist.AcceptSocket();
Thread t = new Thread(new ThreadStart(replay));
t.IsBackground = true;
t.Start();
}
}
private void replay()
{
Socket sc = s;
NetworkStream ns = new NetworkStream(sc);
StreamReader reader = new StreamReader(ns);
StreamWriter writer = new StreamWriter(ns);
string str = "";
string response = "";
try { str = reader.ReadLine(); }
catch { str = "error"; }
if (str == "register")
{
MessageBox.Show("ok");
}
response = "registeredSucss,";
writer.WriteLine(response);
writer.Flush();
ns.Close();
sc.Close();
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(init));
t.IsBackground = true;
t.Start();
MessageBox.Show("Server run!!");
button1.Enabled = false;
}
and IpClient Code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace IpClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpClient tcp;
NetworkStream ns;
StreamReader reader;
StreamWriter writer;
string str = "";
private void button1_Click(object sender, EventArgs e)
{
try
{
tcp = new TcpClient("127.0.0.1",5050);
tcp.ReceiveBufferSize = 25000;
tcp.NoDelay = true;
ns = tcp.GetStream();
reader = new StreamReader(ns);
writer = new StreamWriter(ns);
writer.WriteLine("register");
writer.Flush();
str = reader.ReadLine();
string[] strsplit = null;
strsplit = str.Split(',');
if (strsplit[0] != "registeredSucss")
{
MessageBox.Show("Not connected");
}
else
{
MessageBox.Show("Your connected");
}
}
catch
{
MessageBox.Show("error");
}
}

I wrote a complete example for you.
You can modify it according to your needs.
Simply connecting the client to the server without sending or receiving messages will not disconnect.
In the server and the client, there is a thread that continuously calls the receive function, and sends a message when the connection is disconnected.
byte[] buffer = new byte[1024 * 1024 * 2];
int length = socket.Receive(buffer);
if (length == 0) {
///Write the desired operation
}
"Disconnect when closing the window" uses the formclosing event:
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
}
This is the control diagram used by the two windows:
IpClient:
IpServe:
This is the code for the two windows:
IpClient:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace IpClient {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
Socket socket;//The socket responsible for the connection
private void ConnectB_Click(object sender, EventArgs e) {
//Determine whether to request a connection repeatedly
try {
Log("Connected " + socket.LocalEndPoint.ToString() + "\nPlease do not request the connection repeatedly");
} catch {
//Determine whether the input is wrong
try {
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Create IP address and port number;
IPAddress ip = IPAddress.Parse(Ipbox.Text);
int port = Convert.ToInt32(PortBox.Text);
IPEndPoint iPEndPoint = new IPEndPoint(ip, port);
//Determine whether you can connect to the server
try {
socket.Connect(iPEndPoint);
Log("Connected " + socket.LocalEndPoint.ToString());
//Start receiving data thread
Thread th = new Thread(receive);
th.IsBackground = true;
th.Start();
} catch {
Log("Port is not open");
}
} catch {
socket = null;
Log("Input error");
}
}
}
private void Log(string str) {
ClientLog.AppendText(str + "\r\n");
}
private void receive() {
while (true) {
//Determine whether the data can be received
try {
byte[] buffer = new byte[1024 * 1024 * 2];
int length = socket.Receive(buffer);
if (length == 0) {
Log("Port is not open");
CloseSocket(socket);
socket = null;
break;
}
string txt = Encoding.UTF8.GetString(buffer, 0, length);
Log(socket.RemoteEndPoint + ":\r\t" + txt);
} catch {
break;
}
}
}
private void Form1_Load(object sender, EventArgs e) {
Control.CheckForIllegalCrossThreadCalls = false;
}
private void CloseB_Click(object sender, EventArgs e) {
if (socket != null) {
CloseSocket(socket);
socket = null;
Log("Connection closed");
} else {
Log("Not connected");
}
}
private void SendB_Click(object sender, EventArgs e) {
try {
string txt = SendText.Text;
byte[] buffer = Encoding.ASCII.GetBytes(txt);//ascii encoding
socket.Send(buffer);
} catch {
Log("Not connected");
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
if (socket != null) {
CloseSocket(socket);
socket = null;
}
}
//Disconnect socket
private void CloseSocket(Socket o) {
try {
o.Shutdown(SocketShutdown.Both);
o.Disconnect(false);
o.Close();
} catch {
Log("error");
}
}
}
}
IpServer:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace IpServer {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
Socket socketSend;//Socket responsible for communication
Socket socketListener;//Socket responsible for monitoring
Dictionary<string, Socket> dictionary = new Dictionary<string, Socket>();//Store the connected Socket
private void listnerB_Click(object sender, EventArgs e) {
//Create a listening socket
//SocketType.Stream streaming corresponds to the tcp protocol
//Dgram, datagram corresponds to UDP protocol
socketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try {
//Create IP address and port number;
IPAddress ip = IPAddress.Parse(Ipbox.Text);
int port = Convert.ToInt32(PortBox.Text);
IPEndPoint iPEndPoint = new IPEndPoint(ip, port);
//Let the listening socket bind the ip and port number
socketListener.Bind(iPEndPoint);
Log("Listen successfully" + ip + "\t" + port);
//Set up the listening queue
socketListener.Listen(10);//Maximum number of connections at a time
Thread thread = new Thread(Listen);
thread.IsBackground = true;
thread.Start(socketListener);
} catch {
Log("Failed to listen");
}
}
//Use threads to receive data
private void Listen(object o) {
Socket socket = o as Socket;
while (true) {
//The socket responsible for monitoring is used to receive client connections
try {
//Create a socket responsible for communication
socketSend = socket.Accept();
dictionary.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
clientCombo.Items.Add(socketSend.RemoteEndPoint.ToString());
clientCombo.SelectedIndex = clientCombo.Items.IndexOf(socketSend.RemoteEndPoint.ToString());
Log("Connected " + socketSend.RemoteEndPoint.ToString());
//Start a new thread to receive information from the client
Thread th = new Thread(receive);
th.IsBackground = true;
th.Start(socketSend);
} catch {
continue;
}
}
}
//The server receives the message from the client
private void receive(object o) {
Socket socketSend = o as Socket;
while (true) {
//Try to connect to the client
try {
//After the client connects successfully, the server receives the message from the client
byte[] buffer = new byte[1024 * 1024 * 2];//2M大小
//Number of valid bytes received
int length = socketSend.Receive(buffer);
if (length == 0) {
string tmpIp = socketSend.RemoteEndPoint.ToString();
Log(tmpIp + " Offline");
clientCombo.Items.Remove(tmpIp);
//Try to delete the connection information
try {
clientCombo.SelectedIndex = 0;
} catch {
clientCombo.Text = null;
}
CloseSocket(dictionary[tmpIp]);
dictionary.Remove(tmpIp);
break;
}
string str = Encoding.ASCII.GetString(buffer, 0, length);
Log(socketSend.RemoteEndPoint.ToString() + "\n\t" + str);
} catch {
break;
}
}
}
private void Log(string str) {
ServerLog.AppendText(str + "\r\n");
}
private void Form1_Load(object sender, EventArgs e) {
//Cancel errors caused by cross-thread calls
Control.CheckForIllegalCrossThreadCalls = false;
}
//Send a message
private void SendB_Click(object sender, EventArgs e) {
string txt = SendText.Text;
byte[] buffer = Encoding.UTF8.GetBytes(txt);
try {
string ip = clientCombo.SelectedItem.ToString();//Get the selected ip address
Socket socketsend = dictionary[ip];
socketsend.Send(buffer);
} catch{
Log("Transmission failed");
}
}
private void Close_Click(object sender, EventArgs e) {
try {
try {
string tmpip = socketSend.RemoteEndPoint.ToString();
CloseSocket(dictionary[tmpip]);
dictionary.Remove(tmpip);
clientCombo.Items.Remove(tmpip);
try {
clientCombo.SelectedIndex = 0;
} catch {
clientCombo.Text = null;
}
socketSend.Close();
Log(socketSend.RemoteEndPoint.ToString() + "Offline");
socketListener.Close();
Log("Listener is closed");
} catch{
socketListener.Close();
Log("Listener is closed");
}
} catch {
Log("close error");
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
try {
try {
string tmpip = socketSend.RemoteEndPoint.ToString();
CloseSocket(dictionary[tmpip]);
dictionary.Remove(tmpip);
clientCombo.Items.Remove(tmpip);
try {
clientCombo.SelectedIndex = 0;
} catch {
clientCombo.Text = null;
}
socketSend.Close();
socketListener.Close();
} catch {
socketListener.Close();
}
} catch {
}
}
private void CloseSocket(Socket o) {
try {
o.Shutdown(SocketShutdown.Both);
o.Disconnect(false);
o.Close();
} catch {
Log(o.ToString() + "error");
}
}
}
}
OutPut:
Closing the window causes disconnection:
Disconnect manually:
Transfer data:
If you have any question about my code, please add a comment below.

Related

.NET UDPClient: Error: An existing connection was forcibly closed by the remote host

I had a perfectly fine working console program that uses UdpClient.send to send messages to another program on the localhost (over port 7777). (which oddly enough is an almost identical version this C# script, but running in unity3d, and it has no trouble receiving with the same code).
Now I need to get replies from that program. I added a thread (see bottom) which listens on port 7778 for messages. But I am getting an error when starting saying that:
An existing connection was forcibly closed by the remote host
using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Blaster
{
class Blaster
{
UdpClient client;
IPEndPoint outPoint;
IPEndPoint inPoint;
public int oPort = 7777;
public int iPort = 7778;
public string hostName = "localhost";
public int stepNum = 0;
const int rate = 1000;
public System.Timers.Timer clock;
Thread listener;
static void Main(string[] args)
{
Blaster b = new Blaster();
b.run();
}
Blaster()
{
client = new UdpClient();
outPoint = new IPEndPoint(Dns.GetHostAddresses(hostName)[0], oPort);
inPoint = new IPEndPoint(Dns.GetHostAddresses(hostName)[0], iPort);
}
void run()
{
this.stepNum = 0;
listener = new Thread(new ThreadStart(translater));
listener.IsBackground = true;
listener.Start();
Console.WriteLine("Press Enter to do a send loop...\n");
Console.ReadLine();
Console.WriteLine("started at {0:HH:mm:ss.fff}", DateTime.Now);
start();
Console.WriteLine("Press Enter to stop");
Console.ReadLine();
stop();
client.Close();
}
void stop()
{
clock.Stop();
clock.Dispose();
}
void start()
{
clock = new System.Timers.Timer(rate);
clock.Elapsed += send;
clock.AutoReset = true;
clock.Enabled = true;
}
void send(Object source, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("sending: {0}", stepNum);
Byte[] sendBytes = Encoding.ASCII.GetBytes(message());
try
{
client.Send(sendBytes, sendBytes.Length, outPoint);
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
}
}
string message()
{
Packet p = new Packet();
p.id = "car";
p.start = DateTime.Now;
p.x = 1.2f;
p.y = 0.4f;
p.z = 4.5f;
p.step = stepNum++;
string json = JsonConvert.SerializeObject(p);
return json;
}
void translater()
{
Byte[] data = new byte[0];
client.Client.Bind(inPoint);
while (true)
{
try
{
data = client.Receive(ref inPoint);
}
catch (Exception err)
{
Console.WriteLine("Blaster.translater: recieve data error: " + err.Message);
client.Close();
return;
}
string json = Encoding.ASCII.GetString(data);
Console.WriteLine(json);
Packet p = JsonConvert.DeserializeObject<Packet>(json);
}
}
}
}
Ok, I had seen some examples of folks using a single client object for both send and receive (as well as the same port). But then I saw a different port was needed if they were on the same host. Now I see you need a separate udpClient.
using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Blaster
{
class Blaster
{
UdpClient client;
IPEndPoint outPoint;
IPEndPoint inPoint;
public int oPort = 7777;
public int iPort = 7778;
public string hostName = "localhost";
public int stepNum = 0;
const int rate = 1000;
public System.Timers.Timer clock;
Thread listener;
static void Main(string[] args)
{
Blaster b = new Blaster();
b.run();
}
Blaster()
{
client = new UdpClient();
outPoint = new IPEndPoint(Dns.GetHostAddresses(hostName)[0], oPort);
inPoint = new IPEndPoint(Dns.GetHostAddresses(hostName)[0], iPort);
}
void run()
{
this.stepNum = 0;
listener = new Thread(new ThreadStart(translater));
listener.IsBackground = true;
listener.Start();
Console.WriteLine("Press Enter to do a send loop...\n");
Console.ReadLine();
Console.WriteLine("started at {0:HH:mm:ss.fff}", DateTime.Now);
start();
Console.WriteLine("Press Enter to stop");
Console.ReadLine();
stop();
client.Close();
}
void stop()
{
clock.Stop();
clock.Dispose();
}
void start()
{
clock = new System.Timers.Timer(rate);
clock.Elapsed += send;
clock.AutoReset = true;
clock.Enabled = true;
}
void send(Object source, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("sending: {0}", stepNum);
Byte[] sendBytes = Encoding.ASCII.GetBytes(message());
try
{
client.Send(sendBytes, sendBytes.Length, outPoint);
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
}
}
string message()
{
Packet p = new Packet();
p.id = "car";
p.start = DateTime.Now;
p.x = 1.2f;
p.y = 0.4f;
p.z = 4.5f;
p.step = stepNum++;
string json = JsonConvert.SerializeObject(p);
return json;
}
void translater()
{
UdpClient server = new UdpClient();
Byte[] data = new byte[0];
server.Client.Bind(inPoint);
while (true)
{
try
{
data = server.Receive(ref inPoint);
}
catch (Exception err)
{
Console.WriteLine("Blaster.translater: recieve data error: " + err.Message);
client.Close();
return;
}
string json = Encoding.ASCII.GetString(data);
Console.WriteLine(json);
Packet p = JsonConvert.DeserializeObject<Packet>(json);
}
}
}
}

Display Multiple clients Name at Server side using Socket Connection in WinForms C#

In Windows-Form Application C#, I have done multiple client connection to a single server using socket connection and I can send numbers from multiple clients to single server. But the problem is that, at the server I am not able to differentiate which client is sending which number, so I need to display Client_1, Client_2, Client_3 and so on differently at the server side application. Please let me know how it would be better?
SERVER( at the OnDataReceived() Method how it can be changed?)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Socket_Server
{
public partial class Form1 : Form
{
const int MAX_CLIENTS = 30;
public AsyncCallback pfnWorkerCallBack;
private Socket m_mainSocket;
private Socket[] m_workerSocket = new Socket[30];
private int m_clientCount = 0;
public StreamWriter STW;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string PortNumber = "1755";
try
{
string portStr = PortNumber;
int port = System.Convert.ToInt32(portStr);
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);
m_mainSocket.Bind(ipLocal);
m_mainSocket.Listen(4);
m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
this.BackgroundWorker = new Thread(new ThreadStart(Startinfiniteloop));
this.BackgroundWorker.Start();
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
public void Startinfiniteloop()
{
for (int initial_value = 0; ; initial_value++)
{
try
{
Dictionary<string, int> d2 = new Dictionary<string, int>();
d2["c2"] = initial_value;
this.BeginInvoke((MethodInvoker)(() => Storing_Number.Items.Clear()));
this.BeginInvoke((MethodInvoker)(() => Storing_Number.Items.Add(d2["c2"])));
//Delay Thread
Thread.Sleep(1000);
NumberSend( d2["c2"] + "\n");
this.BeginInvoke((MethodInvoker)(() => Sending_Box.Items.Add("Sending_To_CLIENT: " + d2["c2"] + "\n")));
this.BeginInvoke((MethodInvoker)(() => Sending_Box.TopIndex = Sending_Box.Items.Count - 1));
// this.BackgroundWorker = new Thread(new ThreadStart(NumberSend));
// this.BackgroundWorker.Start();
// STW = new StreamWriter(Sending_Box.Items[initial_value].ToString());
// STW.WriteLine(Sending_Box.Items[initial_value]);
// STW.AutoFlush = true;
}
catch (Exception x)
{
}
}
}
public void NumberSend(string mesg)
{
try
{
Object objData = mesg;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
for (int i = 0; i < m_clientCount; i++)
{
if (m_workerSocket[i] != null)
{
if (m_workerSocket[i].Connected)
{
m_workerSocket[i].Send(byData);
}
}
}
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
public void OnClientConnect(IAsyncResult asyn)
{
try
{
m_workerSocket[m_clientCount] = m_mainSocket.EndAccept(asyn);
WaitForData(m_workerSocket[m_clientCount]);
++m_clientCount;
String str = String.Format("Client # {0} connected", m_clientCount);
Invoke(new Action(() => textBoxMsg.Clear()));
Invoke(new Action(() => textBoxMsg.AppendText(str)));
m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
catch (ObjectDisposedException)
{
System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
public class SocketPacket
{
public System.Net.Sockets.Socket m_currentSocket;
public byte[] dataBuffer = new byte[1024];
}
public void WaitForData(System.Net.Sockets.Socket soc)
{
try
{
if (pfnWorkerCallBack == null)
{
pfnWorkerCallBack = new AsyncCallback(OnDataReceived);
}
SocketPacket theSocPkt = new SocketPacket();
theSocPkt.m_currentSocket = soc;// could be this one!!!
soc.BeginReceive(theSocPkt.dataBuffer, 0,
theSocPkt.dataBuffer.Length,
SocketFlags.None,
pfnWorkerCallBack,
theSocPkt);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState;
int iRx = 0;
iRx = socketData.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(socketData.dataBuffer,
0, iRx, chars, 0);
System.String szData = new System.String(chars);
Invoke(new Action(() => richTextBoxSendMsg.AppendText(szData)));
Invoke(new Action(() => richTextBoxSendMsg.AppendText(Environment.NewLine)));
WaitForData(socketData.m_currentSocket);
}
catch (ObjectDisposedException)
{
System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
CloseSockets();
Close();
}
String GetIP()
{
String strHostName = Dns.GetHostName();
IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);
String IPStr = "";
foreach (IPAddress ipaddress in iphostentry.AddressList)
{
if (ipaddress.IsIPv6LinkLocal == false)
{
IPStr = IPStr + ipaddress.ToString();
return IPStr;
}
}
return IPStr;
}
void CloseSockets()
{
if (m_mainSocket != null)
{
m_mainSocket.Close();
}
for (int i = 0; i < m_clientCount; i++)
{
if (m_workerSocket[i] != null)
{
m_workerSocket[i].Close();
m_workerSocket[i] = null;
}
}
}
public Thread BackgroundWorker { get; set; }
}
}
In OnClientConnect(), the IAsyncResult object should have information on the client. Where you do ++m_clientCount; you could setup a dictionary with the unique info from each client and their ID (IP, port). Then in OnDataReceived() you could just GetClientID(Socket client).
More info can be found on:
https://msdn.microsoft.com/en-us/library/bbx2eya8(v=vs.110).aspx
Note that in the future, please post a simplest version of your issue, so that others don't have to go through the entire code.

Bluetooth Server C# - 32feet

I want my computer to be a bluetooth server, handlig at least 100 connections from smartphones simultaneously. This is the idea:
I start the server and it begin to listen for connections. For each connection it should store the mac adress of the device. Each device should be able to send messages to the server and vice versa.
I've been searching a lot but didnt find a certain way.
How to listen for connections and handle them? Store in array? Start A Thread?
I've been able to start a 1 client server, but coudnt evolve it.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Ports;
using InTheHand.Net.Sockets;
using System.IO;
namespace BluetoothChamada
{
public partial class Form1 : Form
{
List<string> items;
String clientConectedName, clientConectedMAC;
public Form1()
{
InitializeComponent();
items = new List<string>();
}
private void bGo_Click(object sender, EventArgs e)
{
if (serverStarted)
{
updateUI("---Servidor já foi Iniciado---");
return;
}
if (rbServer.Checked)
{
connectAsServer();
}
else
{
Scan();
}
}
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("Procurando dispositivos...");
BluetoothClient client = new BluetoothClient();
devices = client.DiscoverDevicesInRange();
updateUI("Procura finalizada");
updateUI(devices.Length.ToString() + " dispositivos encontrados");
foreach (BluetoothDeviceInfo d in devices)
{
items.Add(d.DeviceName);
}
updateDeviceList();
}
private void connectAsServer()
{
Thread bluetoothServerThread = new Thread(new ThreadStart(ServerConnectThread));
bluetoothServerThread.Start();
}
Guid mUUID = new Guid("00001101-0000-1000-8000-00805F9B34FB");
bool serverStarted = false;
public void ServerConnectThread()
{
serverStarted = true;
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
updateUI("---Servidor Iniciado, aguardando clientes---\r\n\n");
BluetoothClient connection = blueListener.AcceptBluetoothClient();
getData();
updateUI("Cliente: " + clientConectedName + "\r\nMac: " + clientConectedMAC);
Stream mStream = connection.GetStream();
while (true)
{
try
{
byte[] received = new byte[1024];
mStream.Read(received, 0, received.Length);
updateUI(System.Environment.NewLine + "Recebido: " + Encoding.ASCII.GetString(received));
byte[] sent = Encoding.ASCII.GetBytes("FeedBack: OK \r\n");
mStream.Write(sent, 0, sent.Length);
}
catch (IOException exception)
{
updateUI("Cliente foi desconectado");
break;
}
}
}
private void getData()
{
BluetoothClient client = new BluetoothClient();
BluetoothDeviceInfo[] devices = client.DiscoverDevices();
foreach (BluetoothDeviceInfo device in devices)
{
if (!device.Connected)
{
}
else
{
clientConectedName = device.DeviceName;
clientConectedMAC = device.DeviceAddress.ToString();
}
}
}
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);
}
}
}

C# 32feet.Net: Handling two bluetooth connections in seperate threads, gives SocketException

I'm writing a C# console application using the 32feet.Net library that creates two threads to search for and connect to different Bluetooth devices and then open up TCP sockets so that data can be passed to the devices via a network connection. I know this situation sounds completely bizarre, but I've been asked to do this by a senior colleague.
My code seems to work OK with only one device connected, although the Bluetooth connection does sometimes drop out after a couple of messages have been passed backwards and forwards. However, sometimes as soon as the second device connects I get an error saying System.net.sockets.socketexception a connection attempt failed because the connected party did not properly respond, other times the code just exits without throwing any exceptions.
I was wondering what is causing this, I've seen that the 32feet.Net library can support multiple connections. I'm wondering if I've made some errors, as I'm new to C#, .Net, and even Windows, and have never written any Bluetooth based code before.
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace BluetoothManager
{
class Program
{
static void Main(string[] args)
{
BTManager rover_btm = new BTManager();
BTManager base_btm = new BTManager();
base_btm.Port = 0xba5e;
rover_btm.Port = 17825;
base_btm.Name = "Base";
rover_btm.Name = "Rover";
base_btm.match = (args.Length >= 1 && args[0] != "") ? args[0] : "dev1";
rover_btm.match = (args.Length >= 2 && args[1] != "") ? args[1] : "dev2";
Console.WriteLine("Base Station match: " + base_btm.match);
Console.WriteLine("Rover match: " + rover_btm.match);
Thread Base = new Thread(new ThreadStart(base_btm.HandleThread));
Thread Rover = new Thread(new ThreadStart(rover_btm.HandleThread));
Base.Start();
Rover.Start();
Base.Join();
Rover.Join();
Console.Read();
}
}
}
BTManager.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Ports;
using InTheHand.Net.Sockets;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using Microsoft.Win32;
using System.IO;
namespace BluetoothManager
{
class BTManager
{
private static BluetoothDeviceInfo[] peers;
private BluetoothClient client;
private bool _isConnected = false;
private string _match;
private const string defpin = "0000";
private TcpListener tcpListener;
private int _port;
private string _name = "Not Named";
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Port
{
get { return _port; }
set { _port = value; }
}
public bool IsConnected
{
get { return _isConnected; }
private set { _isConnected = value; }
}
public string match
{
get { return _match; }
set { _match = value; }
}
public BTManager()
{
client = new BluetoothClient();
}
public void HandleThread()
{
BluetoothDeviceInfo device;
while (!this.findDevice(out device)) ;
Console.WriteLine("About to pair");
int count = 0;
int max = 5;
while ((!(BluetoothSecurity.PairRequest(device.DeviceAddress, defpin))) && count < max)
{
Console.WriteLine("Pairing Failed, retrying");
count++;
Thread.Sleep(100);
}
if (count == max)
{
HandleThread();
}
else
{
Console.WriteLine("Paired..Beginning connect");
client.BeginConnect(device.DeviceAddress, BluetoothService.SerialPort, this.callback, client);
}
}
private void callback(IAsyncResult result)
{
client.EndConnect(result);
this.tcpListener = new TcpListener(IPAddress.Loopback, _port);
this.tcpListener.Start();
TcpClient TcpClient = this.tcpListener.AcceptTcpClient();
NetworkStream networkStream = TcpClient.GetStream();
Stream bluetoothStream = client.GetStream();
byte[] fromNetwork = new byte[1024];
byte[] fromBluetooth = new byte[1024];
while (client.Connected && TcpClient.Connected)
{
try
{
if (networkStream.CanRead)
{
Array.Clear(fromNetwork, 0, 1024);
networkStream.Read(fromNetwork, 0, 1024);
Console.WriteLine(Encoding.ASCII.GetString(fromNetwork));
bluetoothStream.Write(fromNetwork, 0, 1024);
bluetoothStream.Flush();
while (bluetoothStream.CanRead)
{
Array.Clear(fromBluetooth, 0, 1024);
bluetoothStream.Read(fromBluetooth, 0, 1024);
Console.WriteLine(Encoding.ASCII.GetString(fromNetwork));
networkStream.Write(fromBluetooth, 0, 1024);
networkStream.Flush();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
this.HandleThread();
}
private bool findDevice(out BluetoothDeviceInfo device)
{
peers = client.DiscoverDevicesInRange();
device = Array.Find(peers, element => element.DeviceName == match);
foreach (BluetoothDeviceInfo btdi in peers)
{
Console.WriteLine(btdi.DeviceName);
}
if (device == null)
{
Console.WriteLine(Name +": Not Found");
return false;
}
else
{
Console.WriteLine(Name +": Found");
return true;
}
}
}
}
I am using Sockets in order to communicate with the Bluetooth device.
Its very important to release any resources when disconnecting.
In order to find your COM port you can use this link
Your stream is located here:
System.Net.Sockets.NetworkStream stream = bthClient.GetStream();
Example to how to connect and find your device.
private InTheHand.Net.Sockets.BluetoothClient _BTClient = null;
private InTheHand.Net.Sockets.BluetoothDeviceInfo[] _clientDevices;
/// <summary>
/// Thread function to discover devices
/// </summary>
private void DiscoverBluetoothThread()
{
try
{
_BTClient = new InTheHand.Net.Sockets.BluetoothClient();
_clientDevices = _BTClient.DiscoverDevices(999, _authenticated, _remembered, _unknown);
_BTClient.Dispose();
_BTClient = null;
}
catch (Exception) { }
}
Private void Connect(InTheHand.Net.Sockets.BluetoothDeviceInfo info)
{
string addressN = info.DeviceAddress.ToString("N"); //Format Example: "00066606E014"
string addressC = info.DeviceAddress.ToString("C"); //Format Example: "00:06:66:06:E0:14"
string addressP = info.DeviceAddress.ToString("P"); //Format Example: "00.06.66.06.E0.14"
string addressD = info.DeviceAddress.ToString(); //Format Example: "00066606E014"
string serialPort = FindBluetoothPortName(addressN);
//https://stackoverflow.com/questions/26439091/how-to-get-bluetooth-device-com-serial-port-in-winform-c/27919129#27919129
if (string.IsNullOrEmpty(serialPort) == false && serialPort.Trim().Length > "COM".Length)
bool installed = InstallBluetoothDevice(addressC, passKey, autoConnect);
}
public bool InstallBluetoothDevice(string deviceMACAddress, string passKey, bool connect)
{
string strDevicePassKey = passKey;
string BTMac = deviceMACAddress;
InTheHand.Net.BluetoothAddress BTAddress;
InTheHand.Net.Sockets.BluetoothClient BTClient = new InTheHand.Net.Sockets.BluetoothClient();
InTheHand.Net.BluetoothEndPoint BTEndPoint;
InTheHand.Net.Bluetooth.BluetoothRadio BTRadio;
BTRadio = InTheHand.Net.Bluetooth.BluetoothRadio.PrimaryRadio;
BTRadio.Mode = RadioMode.Connectable;
Guid spguid = BluetoothService.SerialPort;
BTAddress = InTheHand.Net.BluetoothAddress.Parse(BTMac);
BTEndPoint = new InTheHand.Net.BluetoothEndPoint(BTAddress, spguid);
try
{
BluetoothSecurity.PairRequest(BTAddress, strDevicePassKey);
//Application.DoEvents();
BTClient = new InTheHand.Net.Sockets.BluetoothClient();
if (connect)
{
BTClient.Connect(BTEndPoint);
BTEndPoint = new InTheHand.Net.BluetoothEndPoint(BTAddress, spguid);
_connectedDevices.Add(BTAddress, BTClient);
return BTClient.Connected;
}
return true;
}
catch (Exception ex)
{
return false;
}
}

C# client application doesn't receive messages from linux tcp server

Situation:
1. Linux TCP server
2 Windows C# client application
The server receives messages from client, but when I try to send messages from server to the client nothing happens. When I disconnect I get the error:
"Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall." and it points to the line ---> string Response = swRead.ReadLine();
Here is the Client code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace AsynClient
{
public partial class Form1 : Form
{
private TcpClient client;
private StreamWriter swSend;
private StreamReader swRead;
private bool connected = false;
string bojaTekst = "", bojaPoz = "";
private delegate void UpdateLogCallback(string strMessage);
private Thread thrMessag;
public Form1()
{
Application.ApplicationExit += new EventHandler(OnApplicationExit);
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
if (connected == false)
{
InitializeConnection();
}
else
MessageBox.Show("Vec je uspostavljenja konekcija.");
}
private void InitializeConnection()
{
client = new TcpClient();
client.Connect("192.168.100.82", 3456);
swSend = new StreamWriter(client.GetStream()); //prvo mora da se konektuje, pa onda ova komanda
thrMessag = new Thread(new ThreadStart(ReceiveMessages));
thrMessag.Start();
connected = true;
btnSend.Enabled = true;
btnDisconnect.Enabled = true;
txtMsg.Enabled = true;
btnConnect.Enabled = false;
}
private void UpdateLog(string strMessage)
{
txtServ.AppendText(strMessage + "\r\n");
}
private void ReceiveMessages()
{
swRead = new StreamReader(client.GetStream());
string Response = swRead.ReadLine();
while (connected)
{
// Show the messages in the log TextBox
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { swRead.ReadLine() });
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (listBoxTekst.SelectedIndex == -1)
listBoxTekst.SelectedIndex = 0;
if (listBoxPozadina.SelectedIndex == -1)
listBoxPozadina.SelectedIndex = 0;
bojaTekst = listBoxTekst.Text;
bojaPoz = listBoxPozadina.Text;
SendMessage();
}
private void SendMessage()
{
txtMsg.Text);
if (txtMsg.Lines.Length >= 1)
{
swSend.WriteLine(bojaPoz + "\t" + bojaTekst + "\t" + txtMsg.Text + "\t");
swSend.Flush();
txtMsg.Lines = null;
}
txtMsg.Text = "";
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
char[] quit = new char[5];
quit[0] = 'q'; quit[1] = 'w'; quit[2] = 'w'; quit[3] = 'w'; quit[4] = '\0';
connected = false;
btnConnect.Enabled = true;
btnSend.Enabled = false;
btnDisconnect.Enabled = false;
txtMsg.Enabled = false;
swSend.WriteLine(quit);
swSend.Flush();
swSend.Close();
client.Close();
}
public void OnApplicationExit(object sender, EventArgs e)
{
if (connected == true)
{
connected = false;
swSend.WriteLine("qwww"); //proveri da li radi f-ja kako treba
swSend.Flush();
swSend.Close();
client.Close();
}
}
}
}
The server side receives the messages with the read() function and it works fine, but when it sends with write() the C# client doesn't receive the message.
Just one thing (there mioght be other problems):
You have a connected variable, which value you set to true, after you start your listening thread. The loop within the thread doesnt even run once.
thrMessag = new Thread(new ThreadStart(ReceiveMessages));
thrMessag.Start();
connected = true; //here is your first bug, should come before the previos line

Categories