I am creating a TcpServer and TcpClient that the client will connect the server automatically once the server available (keep trying). And I don't want to lose data which means that when client sending data to server and suddenly server down, it will retry again so the below MnitorMiniTcpClientOwn.SendData will keep trying until sucessful.
However there is problem in production that happens randomly where the server will receive multiple same command because of the keep trying loop in SendData request. I am not good in network programming can anyone spot defect in the code?
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
namespace NewCMS.Repositories
{
public class MonitorMiniTcpClientOwn : IDisposable
{
public string ServerIP = "127.0.0.1";
public int Port = 9090;
TcpClient tc = null;
string dataFromClient = string.Empty;
NetworkStream stream = null;
Thread RunningThread = null;
public bool IsRunning = false;
public string _Name = string.Empty;
public virtual string InitialText
{
get
{
return string.Empty;
}
}
public virtual void Start(string name)
{
_Name = name;
if (tc != null)
{
Stop();
}
ThreadStart ts = new ThreadStart(StartThread);
RunningThread = new Thread(ts);
RunningThread.Start();
}
public void StopWithoutAbort()
{
if (tc != null)
{
try
{
tc.Close();
}
catch (Exception ex)
{
}
}
if (stream != null)
{
try
{
stream.Close();
}
catch (Exception ex)
{
}
}
}
public virtual void Stop()
{
try
{
IsRunning = false;
StopWithoutAbort();
if (RunningThread != null)
{
try
{
RunningThread.Abort();
}
catch { }
}
}
catch { }
}
protected void StartThread()
{
IsRunning = true;
while (IsRunning)
{
try
{
tc = new TcpClient();
tc.Connect(ServerIP, Port);
byte[] inStream = new byte[10025];
stream = tc.GetStream();
int read = 0;
while ((read = stream.Read(inStream, 0, inStream.Length)) > 0)
{
dataFromClient += System.Text.Encoding.ASCII.GetString(inStream, 0, read);
string[] strs = dataFromClient.Split('\n');
if (strs != null)
{
for (int i = 0; i < strs.Length - 1; i++)
{
ProcessCommand(tc, strs[i]);
}
if (dataFromClient.EndsWith("\n"))
{
ProcessCommand(tc, strs[strs.Length - 1]);
dataFromClient = string.Empty;
}
else
dataFromClient = strs[strs.Length - 1];
}
}
}
catch (Exception ex)
{
StopWithoutAbort();
if (IsRunning == false)
{
break;
}
IsRunning = true;
Thread.Sleep(1000);
}
}
}
public virtual void ProcessCommand(TcpClient tc, string str)
{
}
public Exception SendData(string text)
{
Exception result = null;
int tryIndex = 0;
int tryCount = 5;
while (tryIndex < tryCount)
{
tryIndex++;
try
{
byte[] bufText = Encoding.Default.GetBytes(text);
stream.Write(bufText, 0, bufText.Length);
result = null;
break;
}
catch (Exception ex)
{
result = ex;
Thread.Sleep(300);
}
}
if (result != null)
{
return result;
}
return result;
}
public void Dispose()
{
Stop();
}
}
}
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace NewCMS.Repositories
{
public class MonitorMiniStoreTcpServerOwn : IDisposable
{
public int Port = 9090;
public TcpListener tl = null;
public Thread RunningThread = null;
public List<Thread> RunningAcceptTcp = new List<Thread>();
public List<MyTcpServerParam> AllConnections = new List<MyTcpServerParam>();
public bool IsRunning = false;
public string _Name = string.Empty;
public virtual void Start(string name)
{
_Name = name;
if (RunningThread != null)
{
Stop();
}
ThreadStart ts = new ThreadStart(StartThread);
RunningThread = new Thread(ts);
RunningThread.Start();
}
public virtual void StopWithoutAbort()
{
if (tl != null)
{
try
{
tl.Stop();
}
catch { }
}
if (AllConnections != null)
{
try
{
for (int i = AllConnections.Count - 1; i >= 0; i--)
{
if (AllConnections[i].Stream != null)
{
try
{
AllConnections[i].Stream.Close();
}
catch { }
}
}
AllConnections.Clear();
}
catch { }
}
if (RunningAcceptTcp != null)
{
try
{
for (int i = RunningAcceptTcp.Count - 1; i >= 0; i--)
{
try
{
RunningAcceptTcp[i].Abort();
}
catch { }
}
RunningAcceptTcp.Clear();
}
catch { }
}
}
public virtual void Stop()
{
try
{
IsRunning = false;
if (tl != null)
{
try
{
tl.Stop();
}
catch (Exception ex)
{
}
}
if (AllConnections != null)
{
try
{
for (int i = AllConnections.Count - 1; i >= 0; i--)
{
if (AllConnections[i].Stream != null)
{
try
{
AllConnections[i].Stream.Close();
}
catch { }
}
}
AllConnections.Clear();
}
catch { }
}
if (RunningAcceptTcp != null)
{
try
{
for (int i = RunningAcceptTcp.Count - 1; i >= 0; i--)
{
try
{
RunningAcceptTcp[i].Abort();
}
catch { }
}
RunningAcceptTcp.Clear();
}
catch { }
}
if (RunningThread != null)
{
try
{
RunningThread.Abort();
}
catch { }
}
}
catch
{
}
}
protected void StartThread()
{
int retry = 0;
IsRunning = true;
while (IsRunning)
{
try
{
tl = new TcpListener(IPAddress.Any, Port);
tl.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
tl.Start();
break;
}
catch (Exception ex)
{
Thread.Sleep(1000);
retry++;
}
}
while (IsRunning)
{
try
{
TcpClient clientSocket = tl.AcceptTcpClient();
MyTcpServerParam p = new MyTcpServerParam();
p.Client = clientSocket;
ParameterizedThreadStart pts = new ParameterizedThreadStart(AcceptSocket);
Thread t = new Thread(pts);
//lock (RunningAcceptTcpSync)
{
RunningAcceptTcp.Add(t);
}
t.Start(p);
}
catch (Exception ex)
{
StopWithoutAbort();
if (IsRunning)
{
ThreadStart ts = new ThreadStart(StartThread);
RunningThread = new Thread(ts);
RunningThread.Start();
}
break;
}
}
}
public void AcceptSocket(object obb)
{
try
{
if (IsRunning == false) return;
byte[] bytesFrom = new byte[10025];
string dataFromClient = string.Empty;
MyTcpServerParam para = (MyTcpServerParam)obb;
NetworkStream networkStream = para.Client.GetStream();
para.Stream = networkStream;
//lock (AllConnectionsSync)
{
AllConnections.Add(para);
}
int read = 0;
while ((read = networkStream.Read(bytesFrom, 0, bytesFrom.Length)) > 0)
{
try
{
dataFromClient += System.Text.Encoding.ASCII.GetString(bytesFrom, 0, read);
string[] strs = dataFromClient.Split('\n');
if (strs != null)
{
for (int i = 0; i < strs.Length - 1; i++)
{
ProcessCommand(para, strs[i]);
}
if (dataFromClient.EndsWith("\n"))
{
ProcessCommand(para, strs[strs.Length - 1]);
dataFromClient = string.Empty;
}
else
dataFromClient = strs[strs.Length - 1];
}
}
catch (Exception ex)
{
}
}
}
catch
{
try
{
//lock (RunningAcceptTcpSync)
{
RunningAcceptTcp.Remove(Thread.CurrentThread);
}
}
catch { }
try
{
MyTcpServerParam para = (MyTcpServerParam)obb;
//lock (AllConnectionsSync)
{
AllConnections.Remove(para);
}
}
catch { }
}
}
public virtual void ProcessCommand(MyTcpServerParam param, string str)
{
}
public Exception SendData(MyTcpServerParam param, string text)
{
Exception result = null;
int tryIndex = 0;
int tryCount = 5;
while (tryIndex < tryCount)
{
try
{
tryIndex++;
byte[] bufText = Encoding.Default.GetBytes(text);
param.Stream.Write(bufText, 0, bufText.Length);
result = null;
break;
}
catch (Exception ex)
{
result = ex;
Thread.Sleep(100);
}
}
if (result != null)
{
try
{
//lock (AllConnectionsSync)
{
AllConnections.Remove(param);
}
}
catch { }
return result;
}
return result;
}
public void Dispose()
{
Stop();
}
}
}
Related
I'm actually able to connect my TcpClient to my TcpServer, but I can't make them communicate. I tried client.GetStream() and BinaryReader/Writer.
Here is my code:
-Client:
public partial class Client : Window
{
#region Constructeurs
public Client() : this(string.Empty, 12221) { }
public Client(string ipDefaut, int portDefaut)
{
InitializeComponent();
numIp.FromString("192.168.2.168");
numPort.Value = portDefaut;
Serveur serveur = new Serveur();
serveur.Show();
}
#endregion
public void Start()
{
if (Ip == null)
return;
if (client == null || client.Client == null)
client = new TcpClient();
if (client.Connected == true)
{
ShowMessage("Déjà connecté.");
return;
}
client = new TcpClient();
try
{
client.ConnectAsync(Ip, Port).Wait(10);
}
catch (SocketException) { }
}
public void Stop()
{
if (client != null && client.Client != null)
if (client.Connected)
{
client.Client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
public string Read()
{
if (client != null && client.GetStream() != null)
if (client.Connected && client.GetStream().DataAvailable)
{
BinaryReader reader = new BinaryReader(client.GetStream());
return reader.ReadString();
}
return string.Empty;
}
public void Send(string info)
{
if (client != null && client.GetStream() != null)
if (client.Connected)
{
BinaryWriter writer = new BinaryWriter(client.GetStream());
writer.Write(info);
writer.Flush();
}
}
private void ShowMessage(string message)
{
labelInfo.Content = message;
Storyboard sb = Resources["sbLabelInfo"] as Storyboard;
sb.Begin(labelInfo);
}
private void Connecter(object sender, RoutedEventArgs e)
{
foreach (string num in numIp.ToStringArray())
if (num == string.Empty)
{
ShowMessage("L'adresse ip doit être complète.");
return;
}
Start();
if (client.Connected)
{
ShowMessage("Connecté");
boutonConnecter.IsEnabled = false;
numIp.IsEnabled = false;
numPort.IsEnabled = false;
boutonAnnuler.Content = "Déconnecter";
}
else
ShowMessage("Impossible de se connecter.");
}
private void Annuler(object sender, RoutedEventArgs e)
{
if ((string)boutonAnnuler.Content == "Annuler")
Close();
else if ((string)boutonAnnuler.Content == "Déconnecter")
{
Stop();
boutonConnecter.IsEnabled = true;
numIp.IsEnabled = true;
numPort.IsEnabled = true;
boutonAnnuler.Content = "Annuler";
}
}
#region Propriétés
public string Ip { get { return numIp.ToString(); } }
public int Port { get { return (int)numPort.Value; } }
#endregion
#region Membres
private TcpClient client = new TcpClient();
#endregion
}
-Server:
public partial class Serveur : Window
{
#region Constructeurs
public Serveur() : this(12221) { }
public Serveur(int numPortDefaut)
{
InitializeComponent();
foreach (IPAddress addr in Dns.GetHostAddresses(Dns.GetHostName()))
if (addr.AddressFamily == AddressFamily.InterNetwork)
numIp.FromString(addr.ToString());
numPort.Value = numPortDefaut;
serveur = new TcpListener(IPAddress.Parse(Ip), Port);
thread = new Thread(Accept);
serveur.Stop();
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
boutonDemarrer.IsEnabled = false;
MessageBox.Show(this, "Connection impossible - Tic Tac Toe", "Impossible de se connecter à internet. Vérifiez votre connection et réessayez.", MessageBoxButton.OK, MessageBoxImage.Warning);
Close();
}
}
#endregion
public void Start()
{
if (serveur != null)
{
try
{
serveur.Start();
}
catch (SocketException) { }
IsConnected = false;
StartThread();
}
else
{
serveur = new TcpListener(IPAddress.Parse(Ip), Port);
Start();
}
}
public void Stop()
{
if (serveur != null)
{
IsConnected = false;
serveur.Stop();
StopThread();
}
}
public void StartThread()
{
if (thread.ThreadState == ThreadState.Stopped)
thread.Start();
}
public void StopThread()
{
if (!IsConnected)
{
IsConnected = true;
while (thread.IsAlive) { }
IsConnected = false;
}
}
private void Accept()
{
while (!IsConnected && serveur != null)
if (serveur.Pending())
{
client = serveur.AcceptTcpClient();
IsConnected = true;
}
}
public string Read()
{
if (client != null && client.GetStream() != null)
if (client.Connected && client.GetStream().DataAvailable)
{
BinaryReader reader = new BinaryReader(client.GetStream());
return reader.ReadString();
}
return string.Empty;
}
public void Send(string info)
{
if (client != null && client.GetStream() != null)
if (client.Connected)
{
BinaryWriter writer = new BinaryWriter(client.GetStream());
writer.Write(info);
writer.Flush();
}
}
private void Demarrer(object sender, RoutedEventArgs e)
{
Start();
boutonAnnuler.Content = "Stop";
boutonDemarrer.IsEnabled = false;
numPort.IsEnabled = false;
numIp.IsEnabled = false;
}
private void Annuler(object sender, RoutedEventArgs e)
{
if ((string)boutonAnnuler.Content == "Annuler")
{
Stop();
Close();
}
else if ((string)boutonAnnuler.Content == "Stop")
{
StopThread();
boutonAnnuler.Content = "Annuler";
boutonDemarrer.IsEnabled = true;
numPort.IsEnabled = true;
numIp.IsEnabled = true;
}
}
#region Propriétés
public string Ip { get { return numIp.ToString(); } }
public int Port { get { return (int)numPort.Value; } }
public bool IsConnected { get; private set; }
#endregion
#region Membres
private TcpListener serveur = null;
private TcpClient client = null;
private Thread thread = null;
#endregion
}
The problem is that, in debug mode, client.GetStream().DataAvailable return always false.
Why does it return that and how do I can solve this ?
(numIp and numPort are some fields that the user needs to fill)
try this:
//tcp server
public class Server
{
private string ip { get; set; }
private int port { get; set; }
private Socket server { get; set; }
public List<ClientInfo> listClientsConnected { get; private set; }
// delegate for events
public delegate void Client_Connected(ClientInfo c);
public delegate void Client_Message(string msg, ClientInfo c);
public Server(string ip, int port)
{
this.ip = ip;
this.port = port;
this.listClientsConnected = new List<ClientInfo>();
}
// start server
public void Start()
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(new IPEndPoint(IPAddress.Parse(this.ip), this.port));
server.Listen(1);
server.BeginAccept(new AsyncCallback(ClientConnected), server);
}
// accept client connection
private void ClientConnected(IAsyncResult res)
{
Socket s = (Socket)res.AsyncState;
Socket client = s.EndAccept(res);
ClientInfo clientInf = new ClientInfo()
{
currentClient = client
};
client.BeginReceive(clientInf.buffer, 0, ClientInfo.BUFFER_SIZE_FOR_MESSAGE, 0, new AsyncCallback(ReceiveMessage), clientInf);
// add client to list
listClientsConnected.Add(clientInf);
if (Cliente_Conneted_Event != null)
Cliente_Conneted_Event(clientInf);
}
// receive message from client
private void ReceiveMessage(IAsyncResult ar)
{
ClientInfo cl = (ClientInfo)ar.AsyncState;
Socket s = cl.currentClient;
int read = s.EndReceive(ar);
string msg = null;
if (read > 0)
{
msg = Encoding.ASCII.GetString(cl.buffer, 0, read);
s.BeginReceive(cl.buffer, 0, ClientInfo.BUFFER_SIZE_FOR_MESSAGE, 0, new AsyncCallback(ReceiveMessage), cl);
}
if (Cliente_Message_Event != null)
Cliente_Message_Event(msg, cl);
}
// send message to client
public void sendMessage(string msg, ClientInfo client)
{
if (client.currentClient != null)
{
if (client.currentClient.Connected && !string.IsNullOrEmpty(msg))
{
client.currentClient.Send(Encoding.ASCII.GetBytes(msg));
}
}
}
//events
public event Client_Connected Cliente_Conneted_Event;
public event Client_Message Cliente_Message_Event;
}
// tcp client
public class Client
{
private Socket client { get; set; }
private string clientName { get; set; }
private string ip { get; set; }
private int port { get; set; }
// delegates
public delegate void Client_Connected(ClientInfo c);
public delegate void Client_Message(string msg, ClientInfo c);
public Client(string ip, int port)
{
this.ip = ip;
this.port = port;
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
// connect client to server
public void Connect()
{
ClientInfo clientInf = new ClientInfo()
{
currentClient = client,
};
client.BeginConnect(new IPEndPoint(IPAddress.Parse(this.ip), this.port), new AsyncCallback(ClientConnected), clientInf);
}
// accept client connection
private void ClientConnected(IAsyncResult res)
{
ClientInfo clientInf = (ClientInfo)res.AsyncState;
clientInf.currentClient.BeginReceive(clientInf.buffer, 0, ClientInfo.BUFFER_SIZE_FOR_MESSAGE, 0, new AsyncCallback(ReceiveMessage), clientInf);
// client connected
if (Cliente_Conneted_Event != null)
Cliente_Conneted_Event(clientInf);
}
// receive message from client
private void ReceiveMessage(IAsyncResult ar)
{
ClientInfo cl = (ClientInfo)ar.AsyncState;
Socket s = cl.currentClient;
int read = s.EndReceive(ar);
string msg = null;
if (read > 0)
{
msg = Encoding.ASCII.GetString(cl.buffer, 0, read);
s.BeginReceive(cl.buffer, 0, ClientInfo.BUFFER_SIZE_FOR_MESSAGE, 0, new AsyncCallback(ReceiveMessage), cl);
}
if (Cliente_Message_Event != null)
Cliente_Message_Event(msg, cl);
}
// send message to client
public void sendMessage(string msg, ClientInfo client)
{
if (client.currentClient != null)
{
if (client.currentClient.Connected && !string.IsNullOrEmpty(msg))
{
client.currentClient.Send(Encoding.ASCII.GetBytes(msg));
}
}
}
public event Client_Connected Cliente_Conneted_Event;
public event Client_Message Cliente_Message_Event;
}
// in my case i used a console application
class Program
{
private static Server server;
static void Main(string[] args)
{
string ip = "127.0.0.1";
int port = 3122;
server = new Server(ip, port);
server.Cliente_Conneted_Event += server_Cliente_Conneted_Event;
server.Start();
// connect client 1
Client client = new Client(ip, port);
client.Connect();
client.Cliente_Message_Event+=client_Cliente_Message_Event;
sendMessageToClient();
Console.ReadKey();
}
//receive message from server
private static void client_Cliente_Message_Event(string msg, ClientInfo c)
{
try {
Console.WriteLine("Msg from Server:"+msg);
}
catch(Exception ex){
Console.WriteLine(ex.Message);
}
}
// client connected to server
private static void server_Cliente_Conneted_Event(ClientInfo c)
{
Console.WriteLine("Client Connected...");
}
// send message to all clients from server
private static void sendMessageToClient()
{
try
{
Console.Write("Msg:");
string msg = Console.ReadLine();
// send message to clients
if (server.listClientsConnected.Count > 0)
{
foreach (ClientInfo client in server.listClientsConnected)
server.sendMessage(msg, client);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
sendMessageToClient();
}
}
}
It was longer than expected... I finally gave up on the TcpClient/Server to use my own sockets.
Here is the result (i made a abstract class in my code because these classes are similar) :
Abstract class :
public abstract partial class Connectable : Window
{
public abstract void Start();
public abstract void Stop();
public void WaitMessage()
{
WaitMessage(new StateObject() { socket = socket });
}
private void WaitMessage(StateObject so)
{
Socket s = so.socket;
int read = s.Receive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None);
so.sb.Append(Encoding.UTF8.GetString(so.buffer, 0, read));
if (s.Available > 0)
WaitMessage(so);
else if (NewMessage != null)
{
NewMessage(so.sb.ToString());
so.sb.Clear();
}
}
public void ReceiveMessage()
{
StateObject state = new StateObject() { socket = socket };
try { socket.BeginReceive(state.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(MessageReceived), state); }
catch (SocketException e) { Console.WriteLine(e.Message); }
}
protected void MessageReceived(IAsyncResult ar)
{
StateObject so = (StateObject)ar.AsyncState;
Socket s = so.socket;
int read = s.EndReceive(ar);
so.sb.Append(Encoding.UTF8.GetString(so.buffer, 0, read));
if (s.Available > 0)
s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(MessageReceived), so);
else if (NewMessage != null)
{
NewMessage(so.sb.ToString());
so.sb.Clear();
}
}
public void SendMessage(string msg)
{
if (socket != null)
{
if (socket.Connected && !string.IsNullOrEmpty(msg))
{
socket.Send(Encoding.UTF8.GetBytes(msg));
}
}
}
protected void ShowMessage(string message)
{
Console.WriteLine(message);
}
public virtual bool IsConnected()
{
if (socket == null)
return false;
return socket.Connected;
}
#region Members
protected Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public Message NewMessage;
#endregion
#region Delegates
public delegate void Message(string message);
#endregion
}
Server class :
public partial class Server : Connectable
{
#region Constructeurs
public Server() : this(12221) { }
public Server(int numPortDefaut)
{
InitializeComponent();
socket = null;
NewMessage += ShowMessage;
foreach (IPAddress addr in Dns.GetHostAddresses(Dns.GetHostName()))
if (addr.AddressFamily == AddressFamily.InterNetwork)
numIp.FromString(addr.ToString());
numPort.Value = numPortDefaut;
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
boutonDemarrer.IsEnabled = false;
MessageBox.Show(this, "Connection impossible - Tic Tac Toe", "Impossible de se connecter à internet. Vérifiez votre connection et réessayez.", MessageBoxButton.OK, MessageBoxImage.Warning);
Close();
}
}
#endregion
public override void Start()
{
if (socketListener.IsBound)
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(false);
socket.Dispose();
socket = null;
}
socketListener.Close();
socketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
try
{
socketListener.Bind(new IPEndPoint(IPAddress.Parse(Ip), Port));
socketListener.Listen(1);
AcceptConnection();
}
catch (SocketException e) { Console.WriteLine(e); }
}
public override void Stop()
{
acceptConnection.Cancel();
if (socket != null)
{
socketListener.Close();
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(false);
socket.Dispose();
socket = null;
}
}
private void AcceptConnection()
{
acceptConnection = new CancellationTokenSource();
new Thread(delegate()
{
try
{
while (socket == null)
{
if (socketListener.Poll(1, SelectMode.SelectRead))
socket = socketListener.Accept();
acceptConnection.Token.ThrowIfCancellationRequested();
}
Dispatcher.Invoke(delegate ()
{
boutonDemarrer.Content = "Jouer";
boutonDemarrer.IsEnabled = true;
});
}
catch (OperationCanceledException e) { Console.WriteLine("Fin de l'attente de connection ({0})", e.Message); }
}).Start();
}
private void ButtonClickStart(object sender, RoutedEventArgs e)
{
if ((string)boutonDemarrer.Content == "Jouer")
Close();
else if ((string)boutonDemarrer.Content == "Démarrer")
{
Start();
boutonAnnuler.Content = "Stop";
boutonDemarrer.IsEnabled = false;
numPort.IsEnabled = false;
}
}
private void ButtonClickCancel(object sender, RoutedEventArgs e)
{
if ((string)boutonAnnuler.Content == "Annuler")
Close();
else if ((string)boutonAnnuler.Content == "Stop")
{
Stop();
boutonAnnuler.Content = "Annuler";
boutonDemarrer.Content = "Démarrer";
boutonDemarrer.IsEnabled = true;
numPort.IsEnabled = true;
}
}
#region Propriétés
public string Ip { get { return numIp.ToString(); } }
public int Port { get { return (int)numPort.Value; } }
#endregion
#region Membres
private Socket socketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private CancellationTokenSource acceptConnection = new CancellationTokenSource();
#endregion
}
Client class :
public partial class Client : Connectable
{
#region Constructeurs
public Client() : this(string.Empty, 12221) { }
public Client(string ipDefaut, int portDefaut)
{
InitializeComponent();
NewMessage += ShowMessage;
numIp.FromString("192.168.2.168");
numPort.Value = portDefaut;
}
#endregion
public override void Start()
{
try
{
socket.Connect(Ip, Port);
boutonConnecter.Content = "Jouer";
numIp.IsEnabled = false;
numPort.IsEnabled = false;
boutonAnnuler.Content = "Déconnecter";
}
catch (SocketException e)
{
Console.WriteLine(e.Message);
}
}
public override void Stop()
{
if (socket.Connected)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
}
private void ButtonClickStart(object sender, RoutedEventArgs e)
{
if ((string)boutonConnecter.Content == "Jouer")
Close();
else if ((string)boutonConnecter.Content == "Connecter")
{
foreach (string num in numIp.ToStringArray())
if (num == string.Empty)
{
ShowMessage("L'adresse ip doit être complète.");
return;
}
Start();
}
}
private void ButtonClickCancel(object sender, RoutedEventArgs e)
{
if ((string)boutonAnnuler.Content == "Annuler")
Close();
else if ((string)boutonAnnuler.Content == "Déconnecter")
{
Stop();
boutonConnecter.IsEnabled = true;
numIp.IsEnabled = true;
numPort.IsEnabled = true;
boutonAnnuler.Content = "Annuler";
boutonConnecter.Content = "Connecter";
}
}
#region Properties
public string Ip { get { return numIp.ToString(); } }
public int Port { get { return (int)numPort.Value; } }
#endregion
}
If it can help someone else... :)
after a long search about reconnecting a client to a server (with a timer) I did find a way that works. well almost works.
Lets say I run 3 clients, when I shutdown the server and re-run it, only one client reconnect
seems like the problem is on the server's side, but can't figure it out.
here's my code (Base class only implements the INotifyPropertyChanged interface):
Client:
class RFClient : Base
{
public enum RFClientType { Sender, Receiver };
#region Properties
System.Threading.Timer _stTimer;
private int serverPort;
private string serverIP;
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
private string cType { get; set; }
private RFClientType _clientType;
public RFClientType ClientType
{
get { return _clientType; }
set
{
_clientType = value;
OnPropertyChanged("ClientType");
}
}
private TcpClient _tcpServer;
public TcpClient TcpServer
{
get { return _tcpServer; }
set { _tcpServer = value; OnPropertyChanged("TcpServer"); }
}
private string _msgRecieved;
public string MsgRecieved
{
get { return _msgRecieved; }
set { _msgRecieved = value; OnPropertyChanged("MsgRecieved"); }
}
private string _errorMSG;
public string ErrorMSG
{
get { return _errorMSG; }
set { _errorMSG = value; OnPropertyChanged("ErrorMSG"); }
}
#endregion
#region ctor
public RFClient(string IP, int Port, RFClientType clientType)
{
_name = Environment.UserName;
this._clientType = clientType;
if (_clientType == RFClientType.Receiver) { cType = "Receiver"; }
else if (_clientType == RFClientType.Sender) { cType = "Sender"; }
this._tcpServer = new TcpClient();
this.serverIP = IP;
this.serverPort = Port;
connectToserver(this._tcpServer, this.serverIP, this.serverPort);
}
#endregion
#region Methods
public void connectToserver(TcpClient tcpServer, string IP, int Port)
{
if (tcpServer != null)
{
try
{
_tcpServer.Connect(IP, Port);
SendMessage("onConnect");
ReadFromServer();
}
catch (Exception ex) { _errorMSG = ex.Message; }
}
}
public async void ReadFromServer()
{
string message;
if (_stTimer != null) { _stTimer.Dispose(); }
await Task.Run(() =>
{
while (true)
{
if (_tcpServer != null && !_tcpServer.Connected)
{
_stTimer = new System.Threading.Timer(Timer_Tick, null, 0, 15000);
break;
}
else
{
try
{
using (NetworkStream readStream = _tcpServer.GetStream())
{
byte[] bytes = new byte[256];
int i;
while ((i = readStream.Read(bytes, 0, bytes.Length)) != 0)
{
message = System.Text.Encoding.GetEncoding("Windows-1255").GetString(bytes, 0, i);
MsgRecieved = message;
}
}
}
catch (Exception ex) { _errorMSG = ex.Message; return; }
}
}
});
}
public async void SendMessage(string Message)
{
if (!_tcpServer.Connected)
{
_errorMSG = "No Connection";
return;
}
if (_tcpServer.Connected)
{
int msgSize;
await Task.Run(() =>
{
msgSize = Message.Length;
byte[] buffer = Encoding.GetEncoding("Windows-1255").GetBytes("$#1type" + cType + "$#2type" + "$#1name" + _name + "$#2name" + "$#1message" + Message + "$#2message");
NetworkStream serverStream = _tcpServer.GetStream();
serverStream.Write(buffer, 0, buffer.Length);
serverStream.Flush();
});
}
}
public void Close()
{
this._tcpServer.Close();
}
public void Timer_Tick(object sender)
{
_tcpServer.Close();
//_tcpServer = null;
_tcpServer = new TcpClient();
while (!_tcpServer.Connected)
{
try
{
connectToserver(_tcpServer, serverIP, serverPort);
break;
}
catch { ErrorMSG = "Cannot connect..."; }
}
}
#endregion
}
Server:
class RFServer : Base
{
#region Propertirs
private int myPort;
private TcpListener serverSocket;
public TcpListener ServerSocket
{
get { return serverSocket; }
set { serverSocket = value; OnPropertyChanged("ServerSocket"); }
}
private ObservableCollection<TcpClient> myclients;
public ObservableCollection<TcpClient> MyClients
{
get { return myclients; }
set { myclients = value; OnPropertyChanged("MyClients"); }
}
private string msgRecieved;
public string MsgRecieved
{
get { return msgRecieved; }
set { msgRecieved = value; OnPropertyChanged("MsgRecieved"); }
}
private string status;
public string Status
{
get { return status; }
set { status = value; OnPropertyChanged("Status"); }
}
private string errorStatus;
public string ErrorStatus
{
get { return errorStatus; }
set { errorStatus = value; OnPropertyChanged("ErrorStatus"); }
}
private string logPath = AppDomain.CurrentDomain.BaseDirectory + "serverRole.txt";
#endregion
#region ctor
public RFServer(IPAddress locallAddress, int Port)
{
this.myPort = Port;
try
{
if (!System.IO.File.Exists(logPath))
{
System.IO.File.Create(logPath).Close();
}
serverSocket = new TcpListener(locallAddress, this.myPort);
serverSocket.Start();
Status = "Server started";
writeLog(logPath, "Server started");
}
catch (Exception ex) { writeLog(logPath, ex.Message); ErrorStatus = ex.Message; }
}
#endregion
#region Methods
public async void ListenToClients()
{
await Task.Run(() =>
{
myclients = new ObservableCollection<TcpClient>();
TcpClient tcpClient = new TcpClient();
while (true)
{
try
{
tcpClient = serverSocket.AcceptTcpClient();
ReadClients(tcpClient);
}
catch (Exception ex) { tcpClient.Close(); writeLog(logPath, string.Format(ex.Message)); ErrorStatus = ex.Message; }
}
});
}
public async void ReadClients(TcpClient tcpClient)
{
string fullDataReceived, clientMessage, clientType, logStr;
string clientName = string.Empty;
await Task.Run(() =>
{
while (tcpClient.Connected)
{
try
{
NetworkStream networkStream = tcpClient.GetStream();
byte[] bytesFrom = new byte[10025];
networkStream.Read(bytesFrom, 0, (int)tcpClient.ReceiveBufferSize);
fullDataReceived = Encoding.GetEncoding("Windows-1255").GetString(bytesFrom);
clientMessage = GetSubstringByString("$#1message", "$#2message", fullDataReceived);
clientType = GetSubstringByString("$#1type", "$#2type", fullDataReceived);
clientName = GetSubstringByString("$#1name", "$#2name", fullDataReceived);
if (clientMessage == "onConnect")
{
logStr = string.Format("Client connected -- Name: {0}, Type: {1}, Message: {2}", clientName, clientType, clientMessage);
writeLog(logPath, logStr);
if (clientType == "Receiver")
{
myclients.Add(tcpClient);
}
networkStream.Flush();
}
else
{
logStr = string.Format("New message from {0}: {1}", clientName, clientMessage);
writeLog(logPath, logStr);
MsgRecieved = string.Format("{0}: {1}", clientName, clientMessage);
SendDataToClients(MsgRecieved);
}
}
catch (Exception ex)
{
if (string.IsNullOrWhiteSpace(clientName)) { clientName = "UnKnown"; }
ErrorStatus += ex.Message + Environment.NewLine;
tcpClient.Close();
writeLog(logPath, string.Format("cannot read from client: {0}{2}Error: {1}",clientName,ex.Message,Environment.NewLine));
}
}
});
}
public async void SendDataToClients(string message)
{
if (myclients.Count > 0)
{
byte[] buffer = Encoding.GetEncoding("Windows-1255").GetBytes(message);
NetworkStream clientStream;
string logStr;
for (int i = 0; i <= myclients.Count - 1; i++)
{
await Task.Run(() =>
{
if (((TcpClient)myclients[i]) != null && ((TcpClient)myclients[i]).Connected)
{
try
{
clientStream = ((TcpClient)myclients[i]).GetStream();
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
logStr = string.Format("Message Sent to {0} Clients. ({1})", myclients.Count, message);
writeLog(logPath, logStr);
Status += "Message Sent to " + myclients.Count + " Clients." + Environment.NewLine;
}
catch
{
((TcpClient)myclients[i]).Close();
myclients.RemoveAt(i);
writeLog(logPath, "client disconnected...");
ErrorStatus = "client disconnected..." + Environment.NewLine;
}
}
else
{
((TcpClient)myclients[i]).Close();
myclients.RemoveAt(i);
writeLog(logPath, "client disconnected...");
ErrorStatus += "client disconnected..." + Environment.NewLine;
}
});
}
}
}
/// <summary>
/// Trim a string between 2 delimiters (strings).
/// </summary>
/// <param name="startString">1st delimiter</param>
/// <param name="endString">2nd delimiter</param>
/// <param name="fullString">Full string</param>
/// <returns></returns>
public string GetSubstringByString(string startString, string endString, string fullString)
{
return fullString.Substring((fullString.IndexOf(startString) + startString.Length), (fullString.IndexOf(endString) - fullString.IndexOf(startString) - startString.Length));
}
public void writeLog(string filePath, string Logcontent)
{
File.AppendAllText(filePath, DateTime.Now + " :::: " + Logcontent + Environment.NewLine);
}
public void CloseServer()
{
writeLog(logPath, "Server Stopped");
this.serverSocket.Stop();
this.myclients.Clear();
}
#endregion
}
ReadClients() is working on a 3rd Thread, I think it should be on the same Thread as ListenToClients().
I have two task which work as producer and consumer, but they don't run in parallel. Second one waits for the first one to compelete. Can you explain why and how can I correct this? I want both of them run at the same time. (I try many varians, but all of them don't work well)
class DirectoryReader
{
private readonly string _dir ;
private Processor[] _processors;
private string[] _files;
private readonly Regex _rx = new Regex(#"([^.\\]+)\.cs");
private Queue<Processor> queue = new Queue<Processor>();
private bool isOff;
private AutoResetEvent isAvailable = new AutoResetEvent(false);
private StreamWriter log = new StreamWriter("Log.txt");
public DirectoryReader(string dir)
{
_dir = dir;
}
public Container[] ProcessAllFiles()
{
_files = Directory.GetFiles(_dir, "*.cs", SearchOption.AllDirectories);
_processors = new Processor[_files.Length];
var thread = Task.Run(() => Compute());
var thread2 = Task.Run(() => Read());
thread.Wait();
}
public void Read()
{
for (var i = 0; i < _files.Length; i++)
{
try
{
var matches = _rx.Matches(_files[i]);
foreach (var match in matches)
{
//Console.WriteLine(match);
lock (log)
{
log.WriteLine(match);
}
}
_processors[i] = new Processor(matches[matches.Count - 1].ToString(), File.ReadAllText(_files[i]));
lock (queue)
{
queue.Enqueue(_processors[i]);
isAvailable.Set();
}
}
catch (IOException ex)
{
Console.WriteLine(ex.Message + _files[i]);
}
}
isOff = true;
}
public void Compute()
{
Processor proc = null;
int ccount = 0;
while (true)
{
lock (queue)
{
if ((ccount = queue.Count) > 0)
{
proc = queue.Dequeue();
}
}
if (ccount == 0)
{
if (isOff)
{
return;
}
else
{
isAvailable.WaitOne();
}
}
if (proc != null)
{
//Some calculations on proc
lock (log)
{
log.WriteLine("+++++" + proc.FileName);
}
}
}
}
}
UPD1: I rewrite this code with using BlockingCollection, but is still doesn't work correct
class DirectoryReader
{
private readonly string _dir ;
private Processor[] _processors;
private string[] _files;
private readonly Regex _rx = new Regex(#"([^.\\]+)\.cs");
private List<Container> answer = new List<Container>();
BlockingCollection<FileContainer> dataItems = new BlockingCollection<FileContainer>();
public DirectoryReader(string dir)
{
_dir = dir;
}
public void ProcessAllFiles()
{
_files = Directory.GetFiles(_dir, "*.cs", SearchOption.AllDirectories);
_processors = new Processor[_files.Length];
var task = Task.Factory.StartNew(Compute);
var task2 = Task.Factory.StartNew(Read);
Task.WaitAll(task, task2);
}
public void Read()
{
for (var i = 0; i < _files.Length; i++)
{
try
{
var matches = _rx.Matches(_files[i]);
dataItems.Add(new FileContainer{
Name = matches[matches.Count - 1].ToString(),
Content = File.ReadAllText(_files[i])});
}
catch (IOException ex)
{
Console.WriteLine(ex.Message + _files[i]);
}
}
dataItems.CompleteAdding();
}
public void Compute()
{
FileContainer proc = null;
while (!dataItems.IsCompleted)
{
try
{
proc = dataItems.Take();
}
catch (InvalidOperationException) { }
if (proc != null)
{
//Some calculations
}
}
}
}
I have this program that creates threads on which i must create queue folders and
check them for files.
Now I noticed my program failed after processing a huge number of files without problems.
I produces a UnauthorizedAccessException so I went looking for that folder and it appears
the folder has been locked out totally?!
Could this be my anti-virus blocking access or is it something I must fix on my thread?
public class worker
{
public bool Stopping = false;
private System.Timers.Timer _timer;
private List<string> _files;
#region Feedback
public event FeedbackHandler Feedback;
public delegate void FeedbackHandler(object sender, string text);
#endregion
#region Properties
private string _name;
public string Name
{
get { return _name; }
}
private string _folder;
public string Folder
{
get { return _folder; }
set { _folder = value; }
}
private string _outfolder = Path.Combine(shared.Root, "out");
public string Outfolder
{
get { return _outfolder; }
set { _outfolder = value; }
}
private string _backupfolder = Path.Combine(shared.Root, "backup");
public string Backupfolder
{
get { return _backupfolder; }
set { _backupfolder = value; }
}
private string _filter = "*.*";
public string Filter
{
get { return _filter; }
set { _filter = value; }
}
private SearchOption _subfolders = SearchOption.TopDirectoryOnly;
public bool Subfolders
{
get { return (_subfolders == SearchOption.AllDirectories); }
set { if (value) { _subfolders = SearchOption.AllDirectories; } else { _subfolders = SearchOption.TopDirectoryOnly; } }
}
#endregion
#region Constructor
public worker(string Name)
{
_name = Name;
_folder = Path.Combine(shared.Root, "queues");
_folder = Path.Combine(_folder, Name);
}
#endregion
#region Destructor
~worker()
{
}
#endregion
#region Control
public void Start()
{
Stopping = false;
Directory.CreateDirectory(_folder);
_timer = new System.Timers.Timer(1);
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
Feedback(this, "[" + _name + "] started!");
}
public void Stop()
{
Stopping = true;
Feedback(this, "[" + _name + "] stopped...");
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (Stopping)
{
_timer.Stop();
_files.Clear();
return;
}
_timer.Stop();
Process();
_timer.Start();
}
#endregion
void Process()
{
if (Directory.Exists(_folder))
{
_files = Directory.GetFiles(_folder, _filter, _subfolders).ToList();
foreach (string _file in _files.ToArray())
{
if (Stopping) { break; }
document _document = new document(_file);
_document.Copy(_backupfolder);
_document.Move(_outfolder);
}
_files = new List<string>();
}
}
}
public class document
{
private string _header;
#region Feedback
public event FeedbackHandler Feedback;
public delegate void FeedbackHandler(object sender, string text);
#endregion
#region Properties
private string _file;
public string File
{
get { return _file; }
}
private job _job;
public job Job
{
get { return _job; }
}
#endregion
#region Constructor
public document(string File)
{
_file = File;
_header = shared.FileOperations.ReadHeader(_file);
_job = new job(_file, _header);
_job.ReadHeader();
}
#endregion Constructor
public void Copy(string Folder)
{
string _backupfile;
_backupfile = Path.Combine(Folder,_job.Name);
_backupfile = Path.Combine(_backupfile,_job.Company);
_backupfile = Path.Combine(_backupfile, DateTime.Now.ToString("yyyy"));
_backupfile = Path.Combine(_backupfile, DateTime.Now.ToString("MMMM"));
Directory.CreateDirectory(_backupfile);
_backupfile = Path.Combine(_backupfile, Path.GetFileName(_file));
shared.FileOperations.CopyFile(_file, _backupfile, true);
}
public void Move(string Folder)
{
string _outfile;
_outfile = Path.Combine(Folder, Path.GetFileNameWithoutExtension(_file));
shared.FileOperations.MoveFile(_file, _outfile, true);
}
}
public struct shared
{
public static string Root
{
get
{
string _base = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
return Directory.GetParent(_base).Parent.FullName.ToString();
}
}
public struct Patterns
{
public const string Header = #"\^?JOB\s(?<JOB>[a-zA-Z0-9]+[0-9]{3})[D]?(?<ACTION>[JFE]+)(?<COMPANY>[A-Z]{2,2})\s" +
#"(?<EMAIL>-emto=.*)?" +
#"-C(?<COPIES>[0-9]{2,2})\s" +
#"-Z""(?<PRINTER>[A-Z0-9]+)""\s" +
#"(?:\^?PAGE 01|(?<FAX>\^?FAX.*)\s\^?PAGE 01?)";
public const string Jump = #"\^PAGE\s[0-9]+";
public const string Pages = #"(\$?PAGE\s)";
public const string Fax = #"\^?FAX FROM_COMPANY\s""(?<FROM>.*)""\s" +
#"\^?FAX FROM_FAX_NUM\s""(?<FFAX>.*)""\s" +
#"\^?FAX FROM_NAME\s""(?<FNAME>.*)""\s" +
#"\^?FAX TO_FAX_NUM\s""(?<TFAX>.*)""\s" +
#"\^?FAX TO_COMPANY\s""(?<TO>.*)""\s" +
#"\^?FAX TO_NAME\s""(?<TNAME>.*)""\s" +
#"\^?FAX WHO\s""(?<WHO>.*)""\s" +
#"\^?FAX ID\s+(?<ID>.*)";
public const string Mail = #"-em([^\s=]+)=(""[^""]*""|[^\s]+)";
public const string Seperator = #"^";
}
public struct FileOperations
{
// Encoding
public static Encoding ReadEncoding = Encoding.GetEncoding(1252);
public static Encoding WriteEncoding = Encoding.UTF8;
// Timeouts
static int Timeout = 1;
static int FileTimeout = 10000; // 10 seconds/file permitted..
// Header
public static string ReadHeader(string SourceFile)
{
return ReadHeader(SourceFile, Patterns.Jump);
}
public static string ReadHeader(string SourceFile, string Beacon)
{
WaitFile(SourceFile);
string r = null;
string l = null;
try
{
StreamReader _reader = new StreamReader(SourceFile, ReadEncoding);
Match _match;
do
{
l = _reader.ReadLine();
r += l + " ";
_match = Regex.Match(l, Beacon);
} while (!_match.Success);
_reader.Close();
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
return r;
}
// Read Contents
public static List<string> ReadFile(string SourceFile)
{
return ReadFile(SourceFile, Patterns.Seperator);
}
public static List<string> ReadFile(string SourceFile, string Seperator)
{
WaitFile(SourceFile);
List<string> lines = new List<string>();
try
{
StreamReader sr = new StreamReader(SourceFile, Encoding.GetEncoding(1250));
string tmp = null;
string line = null;
while (!sr.EndOfStream)
{
line = sr.ReadLine();
if (!string.IsNullOrEmpty(line) && line.Substring(0, 1) == Seperator)
{
if (!string.IsNullOrEmpty(tmp))
{
lines.Add(tmp);
}
tmp = line.Replace(Seperator, "^");
}
else
{
tmp += Environment.NewLine + line;
}
}
sr.Close();
if (!string.IsNullOrEmpty(tmp))
{
lines.Add(tmp);
}
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) {throw ex;}
}
return lines;
}
// Write Contents
public static void WriteFile(string DestinationFile, List<string> Lines)
{
try
{
File.WriteAllLines(DestinationFile, Lines.ToArray(), WriteEncoding);
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
}
public static void WriteFile(string DestinationFile, string Contents)
{
try
{
File.WriteAllText(DestinationFile, Contents);
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
}
// Move File
public static void MoveFile(string SourceFile, string DestinationFile, bool Overwrite)
{
WaitFile(SourceFile);
try
{
string _count = null;
string _destination = Path.GetDirectoryName(DestinationFile);
string _file = Path.GetFileNameWithoutExtension(DestinationFile);
string _extension = Path.GetExtension(DestinationFile);
string[] _files = Directory.GetFiles(_destination, _file + "*");
if (_files.Length > 0)
{
if (Overwrite)
{
for (int x = 0; x <= _files.Length - 1; x++)
{
File.Delete(_files[x]);
}
}
else
{
_count = "_" + (_files.Length - 1).ToString("D4");
}
}
DestinationFile = Path.Combine(_destination, _file + _count + _extension);
File.Move(SourceFile, DestinationFile);
}
catch (Exception ex)
{
if (Debugger.IsAttached) { throw ex; }
}
}
public static void CopyFile(string SourceFile, string DestinationFile, bool Overwrite)
{
WaitFile(SourceFile);
try
{
string _count = null;
string _destination = Path.GetDirectoryName(DestinationFile);
string _file = Path.GetFileNameWithoutExtension(DestinationFile);
string _extension = Path.GetExtension(DestinationFile);
string[] _files = Directory.GetFiles(_destination, _file + "*");
if (_files.Length > 0)
{
if (Overwrite)
{
for (int x = 0; x <= _files.Length - 1; x++)
{
File.Delete(_files[x]);
}
}
else
{
_count = "_" + (_files.Length - 1).ToString("D4");
}
}
DestinationFile = Path.Combine(_destination, _file + _count + _extension);
File.Copy(SourceFile, DestinationFile);
}
catch (Exception ex)
{
if (Debugger.IsAttached) { throw ex; }
}
}
// Delete File
public static void DeleteFile(string SourceFile)
{
WaitFile(SourceFile);
try
{
File.Delete(SourceFile);
}
catch (Exception ex)
{
// todo
if (Debugger.IsAttached) { throw ex; }
}
}
// Check File
static void WaitFile(string SourceFile)
{
Timeout = 1;
while (!File.Exists(SourceFile))
{
System.Threading.Thread.Sleep(Timeout);
Timeout++;
if (Timeout == FileTimeout)
{
// todo
if (Debugger.IsAttached) { throw new Exception("Timout exceeded!"); }
}
}
Timeout = 1;
while (!IsFileReady(SourceFile))
{
System.Threading.Thread.Sleep(Timeout);
Timeout++;
if (Timeout == FileTimeout)
{
// todo
if (Debugger.IsAttached) { throw new Exception("Timout exceeded!"); }
}
}
}
static bool IsFileReady(String SourceFile)
{
try
{
using (FileStream inputStream = File.Open(SourceFile, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}
}
public struct Functions
{
public static string CleanXML(string Text)
{
Text = Text.Replace(#"&", #"&");
Text = Text.Replace(#"<", #"<");
Text = Text.Replace(#">", #">");
Text = Text.Replace(#"""", #""");
Text = Text.Replace(#"'", #"'");
return Text;
}
}
}
void Work(string Name)
{
_worker = _workers.FirstOrDefault(w => w.Name == Name);
if (_worker == null)
{
_worker = new worker(Name);
_worker.Feedback+=new worker.FeedbackHandler(Feedback);
_worker.Folder = Path.Combine(_queuefolder, Name);
_worker.Outfolder = _outfolder;
_worker.Backupfolder = _backupfolder;
_workers.Add(_worker);
Thread _thread = new Thread(_worker.Start);
_thread.Start();
_thread.Join();
}
}
To clarify what i meant:
//worker class
private volatile bool _stopping;
private Thread _thread;
public void Start()
{
_stopping = false;
Directory.CreateDirectory(_folder);
_thread = new Thread(Process);
_thread.Start();
Feedback(this, "[" + _name + "] started!");
}
public void Stop()
{
_stopping = true;
_thread.Join();
Feedback(this, "[" + _name + "] stopped...");
}
private void Process()
{
while(!_stopping)
{
......
Thread.Sleep(100);
}
}
Because the way you are using timers... It's wrong. And while its interesting to know, why windows locks the folder, you should start from doing some refactoring. It might actually solve your problem along the way.
I'm working on a network monitoring application, that pings a (not known) number of hosts. So far I have the code below. I've made a class PingHost with a function zping and I called it with the help of a timer once every 2 seconds to let the 2 pings to finish, even if one of them gets TimedOut. But I think a better solution is to generate a new thread for every ping, so that the ping of every host would be independent.
Can anyone give me a hint how to do this?
namespace pinguin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
PingHost caca = new PingHost();
PingHost caca1 = new PingHost();
this.label1.Text = caca.zping("89.115.14.160");
this.label2.Text = caca1.zping("89.115.14.129");
}
}
public class PingHost
{
public string zping(string dest)
{
Application.DoEvents();
Ping sender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 50;
int failed = 0;
int pingAmount = 5;
string stat = "";
PingReply reply = sender.Send(dest, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
stat = "ok";
}
else
{
stat = "not ok!";
}
return stat;
}
}
}
If you use .NET 4 you can use Parallel.Invoke.
You could handle the Ping.PingCompleted event:
ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);
then use:
ping.SendAsync()
side note: Choose more suitable names for your classes and routines. PingHost is more suitable as a routine name
Once I wrote such a solution (it constantly pings about 300 machines):
public class ManyAdressPing {
private readonly bool bAutoStarted;
private readonly CancellationTokenSource cancel = new CancellationTokenSource();
public ConcurrentDictionary<IPAddress, OneAddressPing> pingi = new ConcurrentDictionary<IPAddress, OneAddressPing>();
public ManyAdressPing(bool AutoStarted = true) {
bAutoStarted = AutoStarted;
}
public int CountPings => pingi.Count;
public void AddPingAddress(IPAddress addr, int msTimeOut = 3000, int BetweenPing = 3000) {
var oap = new OneAddressPing(addr, cancel.Token, msTimeOut, BetweenPing);
if (bAutoStarted) oap.Start();
pingi.TryAdd(oap.ipAddress, oap);
}
public void RemovePingAddress(IPAddress addr) {
if (pingi.TryRemove(addr, out var p)) p.Stop();
}
public void Stop() {
cancel.Cancel();
foreach (var pair in pingi) pair.Value.Stop();
}
public PingReply GetReply(IPAddress addr) {
if (pingi.ContainsKey(addr)) return pingi[addr].GetReply();
return null;
}
public Tuple<long, long> GetSuccessOperation(IPAddress addr) {
if (pingi.ContainsKey(addr)) return pingi[addr].GetSuccessOperation();
return null;
}
public PingReply[] GetReply() {
PingReply[] ret = pingi.Values.Select(x=>x.GetReply()).ToArray();
return ret;
}
public PingInfo GetPingInfo(IPAddress addr) {
if (pingi.ContainsKey(addr)) {
var ret = new PingInfo();
var p = pingi[addr];
ret.reply = p.GetReply();
ret.SuccessPing = p._SuccessReply;
ret.FailPing = p._FailReply;
ret.LastSuccessPing = p.LastSuccessfullPing;
return ret;
}
return null;
}
public bool IsPinged(IPAddress addr) {
if (pingi.ContainsKey(addr)) return true;
return false;
}
public IPAddress[] GetAddressesPing() {
return pingi.Keys.ToArray();
}
}
public class PingInfo {
public PingReply reply;
public long SuccessPing = 0;
public long FailPing = 0;
public DateTime LastSuccessPing;
public override string ToString() {
return $"Sping: {SuccessPing} last={LastSuccessPing}, Fping:{FailPing}, reply:{reply}";
}
}
public class OneAddressPing {
public static byte[] bu = {
0
};
public long _FailReply;
public long _SuccessReply;
private bool bStop = false;
private readonly CancellationToken cancellationToken;
public DateTime LastSuccessfullPing = DateTime.MinValue;
public int mSecBetweenPing = 3000;
public Ping ping;
public PingOptions popt;
private Task pTask;
// Here is a self-written LIFO stack
public LightQueue<PingReply> replys = new LightQueue<PingReply>(10);
private readonly AutoResetEvent reset = new AutoResetEvent(false);
private Logger log = null;
private Task pinging = null;
public OneAddressPing(IPAddress addr, CancellationToken ct, int timeOut = 3000, int BetweenPing = 3000, Logger _log =null) {
ipAddress = addr;
popt = new PingOptions();
popt.DontFragment = false;
cancellationToken = ct;
mSecTimeOut = timeOut;
mSecBetweenPing = BetweenPing;
log = _log;
}
public int mSecTimeOut { get; set; } = 3000;
public IPAddress ipAddress { get; set; }
public int CountPings => replys.Length;
private void SetReply(PingReply rep) {
if (rep == null) return;
replys.Put(rep);
if (rep.Status == IPStatus.Success) {
Interlocked.Increment(ref _SuccessReply);
LastSuccessfullPing = DateTime.Now;
} else {
Interlocked.Increment(ref _FailReply);
}
}
public async Task Start() {
if (pTask == null || pTask.Status != TaskStatus.Running) {
ping = new Ping();
Task.Factory.StartNew(PingCircle, TaskCreationOptions.RunContinuationsAsynchronously | TaskCreationOptions.LongRunning); pTask = Task.Run(PingCircle, cancellationToken);
}
}
public void Stop() {
if (pTask.Status == TaskStatus.Running) {
bStop = true;
try {
pTask.Wait(mSecTimeOut, cancellationToken);
} catch (Exception ex) {
log.ErrorSource($"Error ping stop: {ex.Message}");
}
}
}
private async Task PingCircle() {
while (cancellationToken.IsCancellationRequested == false && !bStop) {
try {
try {
PingReply rep = await ping.SendPingAsync(ipAddress, mSecTimeOut, bu,popt);
if (rep != null) SetReply(rep);
} catch (PingException p) {
// ignore ping error
Debug.WriteLine($"error: {p}");
} catch (Exception ee) {
log?.ErrorSource(ee);
Debug.WriteLine($"error: {ee}");
}
await Task.Delay(mSecBetweenPing, cancellationToken);
} catch (Exception ee) {
log?.ErrorSource(ee);
}
}
}
public PingReply GetReply() {
if (replys.IsEmpty) return null;
return replys.PeekLast(0);
}
public Tuple<long, long> GetSuccessOperation() {
return new Tuple<long, long>(_SuccessReply, _FailReply);
}
public bool LongPingSuccess() {
int ret = 0;
for (int i = 0; i < 5; i++) {
var r = replys.PeekLast(i);
if (r.Status == IPStatus.Success) ret++;
}
if (ret > 2) return true;
return false;
}
}