C#, tcpClient to Multiple IP Address but on the same port - c#

Scenario:
I have multiple machines, each wit hit's own IP, that run a tcpServer, all on the same port. During each transaction data is sent if the tcpServer port is opened. It, looks for a client before opening the port.
What I Need:
I'm writing an app, that needs to:
1. Check through the list of IP's if they are availible
2. Open a tcpClient port to each machine IP, (all on the same ports)
3. After every specified time make sure the connection is open, if not reopen connection.
Future:
I use an XMl file to give the SQL data which is used to get the list of machines and the port to listen on. In this xml is a udp setting as well, if this is yes, then the data being sent, must be received and redirected to a specified UDP port.
The Class:
public static void tcpListen(IPAddress server, int port)
{
try
{
TcpListener listener = new TcpListener(server, port);
listener.AcceptTcpClient();
listener.Start();
while (true)
{
Socket client = listener.AcceptSocket();
var childSocketThread = new Thread(() =>
{
byte[] data = new byte[100];
int size = client.Receive(data);
for (int i = 0; i < size; i++)
feedback = server + ":" + port + ": " + Convert.ToChar(data[i]);
using (StreamWriter w = File.AppendText("TCPLog.log"))
{
Log(feedback, w);
}
client.Close();
});
childSocketThread.Start();
}
}
catch (Exception err)
{
using (StreamWriter w = File.AppendText("error.log"))
{
Log("tcpControl.tcpListen: " + err.Message, w);
}
}
}
The part of the code that repeats every few seconds:
private void ptoCheck()
{
IPAddress sourceIP;
int sourcePort;
int destinationPort;
string tcpStatus;
int oldCOunt = dgvWorkstations.RowCount;
int newCount = sqlScripts.posCount(sqlServer, sqlUser, sqlPassword, sqlDatabase);
if (newCount != oldCOunt)
{
getWorkstations();
}
try
{
foreach (DataGridViewRow row in dgvWorkstations.Rows)
{
int i = row.Index;
bool tcpState;
dgvWorkstations["Status", i].Value = "Checking";
dgvWorkstations.Refresh();
name = row.Cells["POS_Name"].Value.ToString();
sourceIP = IPAddress.Parse(row.Cells["LastKnownIP"].Value.ToString());
sourcePort = Convert.ToInt32(row.Cells["Receive_Port"].Value.ToString());
destinationPort = Convert.ToInt32(row.Cells["Send_Port"].Value.ToString());
tcpState = tcpControl.tcpCheck(sourceIP, sourcePort, name);
if (tcpState == false)
{
dgvWorkstations["Status", i].Value = "Connecting";
dgvWorkstations.Refresh();
tcpStatus = tcpControl.tcpConnect(sourceIP, sourcePort, name);
tcpControl.tcpListen(sourceIP, sourcePort);
dgvWorkstations["Status", i].Value = tcpStatus;
}
if (tcpState == true)
{
dgvWorkstations["Status", i].Value = "Connected";
dgvWorkstations.Refresh();
}
i = i + 1;
}
}
catch (Exception err)
{
using (StreamWriter w = File.AppendText("AError.log"))
{
Log("frmMain.ptoCheck: (" + name + ") " + err.Message, w);
}
}//End Catch
}

I got the following code toe work, from my class I can now make multiple connections, however. The part where I call another method to listen and receive the data blocks the first method and holds it untill the connection drops without making further connections.
My Class:
public void tcpTest2(IPAddress server, Int32 port, int x)
{
TcpClient client;
sendData("Connecting to Host: " + server + " on port: " + port.ToString() + "...");
sendStatus("Connecting", x);
try
{
client = new TcpClient(server.ToString(), port);
if (false)
{
}
if (true)
{
sendData("Connection to Host: " + server + " on port: " + port.ToString() + "..ESTABLISHED");
sendStatus("Connected", x);
receiveData(client, server, port);
}
}
catch (Exception)
{
sendData("Connection to Host: " + server + " on port: " + port.ToString() + "..FAILED");
sendStatus("Failed", x);
}
}
public void receiveData(TcpClient client, IPAddress server, int port)
{
Byte[] data = System.Text.Encoding.Default.GetBytes("|");
data = new byte[1024];
string stringData;
bool connected;
connected = true;
while (connected == true)
{
string fromC = client.Client.RemoteEndPoint.ToString();
NetworkStream ns = client.GetStream();
int recv = ns.Read(data, 0, data.Length);
stringData = Encoding.ASCII.GetString(data, 0, recv);
sendUpdate("{" + fromC + "}" + stringData);
connected = IsConnected(client);
}
if (connected == false)
{
sendData("Connection to Host: " + server + " on port: " + port.ToString() + "..LOST");
sendLost(server);
}
}
public bool IsConnected(TcpClient client)
{
try
{
if (client != null && client.Client != null && client.Client.Connected)
{
if (client.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if (client.Client.Receive(buff, SocketFlags.Peek) == 0)
{
return false;
}
else
{
return true;
}
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
}

Here is the final code that worked for me:
My Class:
public void tcpConnect(object pos)
{
IPAddress hostIP = IPAddress.Parse(pos.ToString().Split(':')[0]);
int hostPort = Int32.Parse(pos.ToString().Split(':')[1]);
rowInd = Int32.Parse(pos.ToString().Split(':')[2]);
var client = new TcpClient();
if (!client.ConnectAsync(hostIP, hostPort).Wait(1000))
{
sendData("Connection to Host: " + hostIP + " on port: " + hostPort.ToString() + ".FAILED");
sendStatus("Failed", "", rowInd);
return;
}
if (true)
{
sendData("Connection to Host: " + hostIP.ToString() + " on port: " + hostPort.ToString() + "..ESTABLISHED");
Thread thread = new Thread(new ParameterizedThreadStart(ClientHandler));
thread.IsBackground = true;
Thread.FreeNamedDataSlot(hostIP.ToString() + rowInd.ToString());
thread.Name = hostIP.ToString() + rowInd.ToString();
thread.Start(client);
threadID = thread.ManagedThreadId.ToString();
sendStatus("Connected", threadID, rowInd);
}
}
public bool IsConnected(TcpClient client)
{
try
{
if (client != null && client.Client != null && client.Client.Connected)
{
if (client.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if (client.Client.Receive(buff, SocketFlags.Peek) == 0)
{
return false;
}
else
{
return true;
}
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
public void ClientHandler(object c)
{
TcpClient client = (TcpClient)c;
NetworkStream netstream = client.GetStream();
string fromC = client.Client.RemoteEndPoint.ToString();
string fromIP = fromC.Split(':')[0];
bool connected = true;
while (connected)
{
Thread.Sleep(10);
try
{
byte[] data = new byte[client.ReceiveBufferSize];
data = System.Text.Encoding.Default.GetBytes("|");
data = new byte[1024];
string stringData;
NetworkStream ns = client.GetStream();
int recv = ns.Read(data, 0, data.Length);
stringData = Encoding.ASCII.GetString(data, 0, recv);
sendUpdate("|" + fromC + "|" + stringData);
connected = IsConnected(client);
}
catch (Exception err)
{
connected = false;
sendLost(fromIP);
using (StreamWriter w = File.AppendText("Arch-PTO.log"))
{
Log("tcpServices.ClientHandler: " + err.Message, w);
}
}
}
sendLost(fromIP);
}

Related

Connection Refused to Server when using SOCKS5 Proxy and Tor C#

I have this code that uses SOCKS5 Proxy to connect to Tor and then tries to connect the Client to the remote Server on a VPS machine that runs a C# server. The problem is I can't establish the connection.
The Server is written in C#, it listens to connections on port 1604 and it's a hidden service meaning any traffic that comes trough port 1604 will be redirected to 127.0.0.1:1604 where my server listens.
Test 1
When I connected directly to test if my client get make a HTTP request to a webserver on port 80 it works, when i use the .onion address to access the webserver it works too. When I check yougetsignal using the remote machine IP it's open as you can see
Also here is the torrc FILE config
GREAT EVERYTHING WORKS SO FAR, BUT WAIT A SECOND
Test 2
When I try to connect the client to my standalone server (not a webserver) directly it works like I expected it to do, but when i try to use the HOSTNAME generated by tor.exe (the same HOSTNAME I used in Test 1) i get Connection Refused and General SOCKS server failure.
I can't find what I'm doing wrong and why I can't reach my server, please assist me and thank you for your time.
The Code
Client
Socks Code
public class ConnectionException : ApplicationException
{
public ConnectionException(string message)
: base(message)
{
}
}
/// <summary>
/// Provides sock5 functionality to clients (Connect only).
/// </summary>
public class SocksProxy
{
private SocksProxy() { }
#region ErrorMessages
private static string[] errorMsgs = {
"Operation completed successfully.",
"General SOCKS server failure.",
"Connection not allowed by ruleset.",
"Network unreachable.",
"Host unreachable.",
"Connection refused.",
"TTL expired.",
"Command not supported.",
"Address type not supported.",
"Unknown error."
};
#endregion
public static Socket ConnectToSocks5Proxy(string proxyAdress, ushort proxyPort, string destAddress, ushort destPort,
string userName, string password)
{
IPAddress destIP = null;
IPAddress proxyIP = null;
byte[] request = new byte[257];
byte[] response = new byte[257];
ushort nIndex;
try
{
proxyIP = IPAddress.Parse(proxyAdress);
}
catch (FormatException)
{ // get the IP address
proxyIP = Dns.GetHostByAddress(proxyAdress).AddressList[0];
}
// Parse destAddress (assume it in string dotted format "212.116.65.112" )
try
{
destIP = IPAddress.Parse(destAddress);
}
catch (FormatException)
{
// wrong assumption its in domain name format "www.microsoft.com"
}
IPEndPoint proxyEndPoint = new IPEndPoint(proxyIP, proxyPort);
// open a TCP connection to SOCKS server...
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(proxyEndPoint);
nIndex = 0;
request[nIndex++] = 0x05; // Version 5.
request[nIndex++] = 0x01; // 2 Authentication methods are in packet...
request[nIndex++] = 0x00; // NO AUTHENTICATION REQUIRED
//request[nIndex++] = 0x02; // USERNAME/PASSWORD
// Send the authentication negotiation request...
s.Send(request, nIndex, SocketFlags.None);
// Receive 2 byte response...
int nGot = s.Receive(response, 2, SocketFlags.None);
if (nGot != 2)
throw new ConnectionException("Bad response received from proxy server.");
if (response[1] == 0xFF)
{ // No authentication method was accepted close the socket.
s.Close();
throw new ConnectionException("None of the authentication method was accepted by proxy server.");
}
byte[] rawBytes;
if (/*response[1]==0x02*/false)
{//Username/Password Authentication protocol
nIndex = 0;
request[nIndex++] = 0x05; // Version 5.
// add user name
request[nIndex++] = (byte)userName.Length;
rawBytes = Encoding.Default.GetBytes(userName);
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
// add password
request[nIndex++] = (byte)password.Length;
rawBytes = Encoding.Default.GetBytes(password);
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
// Send the Username/Password request
s.Send(request, nIndex, SocketFlags.None);
// Receive 2 byte response...
nGot = s.Receive(response, 2, SocketFlags.None);
if (nGot != 2)
throw new ConnectionException("Bad response received from proxy server.");
if (response[1] != 0x00)
throw new ConnectionException("Bad Usernaem/Password.");
}
// This version only supports connect command.
// UDP and Bind are not supported.
// Send connect request now...
nIndex = 0;
request[nIndex++] = 0x05; // version 5.
request[nIndex++] = 0x01; // command = connect.
request[nIndex++] = 0x00; // Reserve = must be 0x00
if (destIP != null)
{// Destination adress in an IP.
switch (destIP.AddressFamily)
{
case AddressFamily.InterNetwork:
// Address is IPV4 format
request[nIndex++] = 0x01;
rawBytes = destIP.GetAddressBytes();
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
break;
case AddressFamily.InterNetworkV6:
// Address is IPV6 format
request[nIndex++] = 0x04;
rawBytes = destIP.GetAddressBytes();
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
break;
}
}
else
{// Dest. address is domain name.
request[nIndex++] = 0x03; // Address is full-qualified domain name.
request[nIndex++] = Convert.ToByte(destAddress.Length); // length of address.
rawBytes = Encoding.Default.GetBytes(destAddress);
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
}
// using big-edian byte order
byte[] portBytes = BitConverter.GetBytes(destPort);
for (int i = portBytes.Length - 1; i >= 0; i--)
request[nIndex++] = portBytes[i];
// send connect request.
s.Send(request, nIndex, SocketFlags.None);
// Point of breaking !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
s.Receive(response); // Get variable length response...
if (response[1] != 0x00)
throw new ConnectionException(errorMsgs[response[1]]); // Crashes the Client !!!!!!!!!!!
// Success Connected...
return s;
}
}
Main Code
Socket s;
// s = SocksProxy.ConnectToSocks5Proxy("127.0.0.1", 9150, "xoembwt22tmxseask2qyuudbxoubiuafw54klkwuktvv6bxbhrdffqyd.onion", 1604, "U$er", "Pa$$word!"); //NOT WORKING
//s = SocksProxy.ConnectToSocks5Proxy("127.0.0.1", 9150, "xoembwt22tmxseask2qyuudbxoubiuafw54klkwuktvv6bxbhrdffqyd.onion", 80, "", ""); // WORKING
s = SocksProxy.ConnectToSocks5Proxy("127.0.0.1", 9150, "xoembwt22tmxseask2qyuudbxoubiuafw54klkwuktvv6bxbhrdffqyd.onion", 1604, "", ""); //NOT WORKING
// s = SocksProxy.ConnectToSocks5Proxy("127.0.0.1", 9150, "X.X.X.100", 1604, "", ""); //WORKING
//client is a TCPClient
client.Client = s;
Server
Server Class
public class Server : Common
{
private static int counter;
private readonly ConcurrentDictionary<int, ClientToken> clients = new ConcurrentDictionary<int, ClientToken>();
public TcpListener listener;
private Thread listenerThread;
public bool Active => listenerThread != null && listenerThread.IsAlive;
public static int NextConnectionId()
{
int id = Interlocked.Increment(ref counter);
if (id == int.MaxValue) throw new Exception("connection id limit reached: " + id);
return id;
}
private void Listen(int port)
{
try
{
listener = new TcpListener(new IPEndPoint(IPAddress.Any, port));
listener.Server.NoDelay = NoDelay;
listener.Server.SendTimeout = SendTimeout;
listener.Start();
Logger.Log("Server: listening port=" + port);
while (true)
{
TcpClient client = listener.AcceptTcpClient();
int connectionId = NextConnectionId();
ClientToken token = new ClientToken(client);
clients[connectionId] = token;
Thread sendThread = new Thread(() =>
{
try
{
SendLoop(connectionId, client, token.sendQueue, token.sendPending);
}
catch (ThreadAbortException) { }
catch (Exception exception)
{
Logger.LogError("Server send thread exception: " + exception);
}
});
sendThread.IsBackground = true;
sendThread.Start();
Thread receiveThread = new Thread(() =>
{
try
{
ReceiveLoop(connectionId, client, receiveQueue, MaxMessageSize);
clients.TryRemove(connectionId, out ClientToken _);
sendThread.Interrupt();
}
catch (Exception exception)
{
Logger.LogError("Server client thread exception: " + exception);
}
});
receiveThread.IsBackground = true;
receiveThread.Start();
}
}
catch (ThreadAbortException exception)
{
Logger.Log("Server thread aborted. That's okay. " + exception);
}
catch (SocketException exception)
{
Logger.Log("Server Thread stopped. That's okay. " + exception);
}
catch (Exception exception)
{
Logger.LogError("Server Exception: " + exception);
}
}
public bool Start(int port)
{
if (Active) return false;
receiveQueue = new ConcurrentQueue<Message>();
Logger.Log("Server: Start port=" + port);
listenerThread = new Thread(() => { Listen(port); });
listenerThread.IsBackground = true;
listenerThread.Priority = ThreadPriority.BelowNormal;
listenerThread.Start();
return true;
}
public void Stop()
{
if (!Active) return;
Logger.Log("Server: stopping...");
listener?.Stop();
listenerThread?.Interrupt();
listenerThread = null;
foreach (KeyValuePair<int, ClientToken> kvp in clients)
{
TcpClient client = kvp.Value.client;
try
{
client.GetStream().Close();
}
catch { }
client.Close();
}
clients.Clear();
}
public bool Send(int connectionId, byte[] data)
{
if (data.Length <= MaxMessageSize)
{
ClientToken token;
if (clients.TryGetValue(connectionId, out token))
{
token.sendQueue.Enqueue(data);
token.sendPending.Set();
return true;
}
Logger.Log("Server.Send: invalid connectionId: " + connectionId);
return false;
}
Logger.LogError("Client.Send: message too big: " + data.Length + ". Limit: " + MaxMessageSize);
return false;
}
public string GetClientAddress(int connectionId)
{
ClientToken token;
if (clients.TryGetValue(connectionId, out token))
return ((IPEndPoint) token.client.Client.RemoteEndPoint).Address.ToString();
return "";
}
public bool Disconnect(int connectionId)
{
ClientToken token;
if (clients.TryGetValue(connectionId, out token))
{
token.client.Close();
Logger.Log("Server.Disconnect connectionId:" + connectionId);
return true;
}
return false;
}
private class ClientToken
{
public readonly TcpClient client;
public readonly ManualResetEvent sendPending = new ManualResetEvent(false);
public readonly SafeQueue<byte[]> sendQueue = new SafeQueue<byte[]>();
public ClientToken(TcpClient client)
{
this.client = client;
}
}
}
Common
public abstract class Common
{
public static int messageQueueSizeWarning = 100000;
public int MaxMessageSize = 2147483647;
public bool NoDelay = true;
protected ConcurrentQueue<Message> receiveQueue = new ConcurrentQueue<Message>();
public int SendTimeout = 5000;
public int ReceiveQueueCount => receiveQueue.Count;
public bool GetNextMessage(out Message message)
{
return receiveQueue.TryDequeue(out message);
}
protected static bool SendMessagesBlocking(NetworkStream stream, byte[][] messages)
{
try
{
int packetSize = 0;
for (int i = 0; i < messages.Length; ++i)
packetSize += sizeof(int) + messages[i].Length;
byte[] payload = new byte[packetSize];
int position = 0;
for (int i = 0; i < messages.Length; ++i)
{
byte[] header = Utils.IntToBytesBigEndian(messages[i].Length);
Array.Copy(header, 0, payload, position, header.Length);
Array.Copy(messages[i], 0, payload, position + header.Length, messages[i].Length);
position += header.Length + messages[i].Length;
}
stream.Write(payload, 0, payload.Length);
return true;
}
catch (Exception exception)
{
Logger.Log("Send: stream.Write exception: " + exception);
return false;
}
}
protected static bool ReadMessageBlocking(NetworkStream stream, int MaxMessageSize, out byte[] content)
{
content = null;
byte[] header = new byte[4];
if (!stream.ReadExactly(header, 4))
return false;
int size = Utils.BytesToIntBigEndian(header);
if (size <= MaxMessageSize)
{
content = new byte[size];
return stream.ReadExactly(content, size);
}
Logger.LogWarning("ReadMessageBlocking: possible allocation attack with a header of: " + size + " bytes.");
return false;
}
protected static void ReceiveLoop(int connectionId, TcpClient client, ConcurrentQueue<Message> receiveQueue,
int MaxMessageSize)
{
NetworkStream stream = client.GetStream();
DateTime messageQueueLastWarning = DateTime.Now;
try
{
receiveQueue.Enqueue(new Message(connectionId, EventType.Connected, null));
while (true)
{
byte[] content;
if (!ReadMessageBlocking(stream, MaxMessageSize, out content))
break;
receiveQueue.Enqueue(new Message(connectionId, EventType.Data, content));
if (receiveQueue.Count > messageQueueSizeWarning)
{
TimeSpan elapsed = DateTime.Now - messageQueueLastWarning;
if (elapsed.TotalSeconds > 10)
{
Logger.LogWarning("ReceiveLoop: messageQueue is getting big(" + receiveQueue.Count +
"), try calling GetNextMessage more often. You can call it more than once per frame!");
messageQueueLastWarning = DateTime.Now;
}
}
}
}
catch (Exception exception)
{
Logger.Log("ReceiveLoop: finished receive function for connectionId=" + connectionId + " reason: " +
exception);
}
stream.Close();
client.Close();
receiveQueue.Enqueue(new Message(connectionId, EventType.Disconnected, null));
}
protected static void SendLoop(int connectionId, TcpClient client, SafeQueue<byte[]> sendQueue,
ManualResetEvent sendPending)
{
NetworkStream stream = client.GetStream();
try
{
while (client.Connected)
{
sendPending.Reset();
byte[][] messages;
if (sendQueue.TryDequeueAll(out messages))
if (!SendMessagesBlocking(stream, messages))
return;
sendPending.WaitOne();
}
}
catch (ThreadAbortException) { }
catch (ThreadInterruptedException) { }
catch (Exception exception)
{
Logger.Log("SendLoop Exception: connectionId=" + connectionId + " reason: " + exception);
}
}
}

Console application crashing

Hi guys i have here a console application written in c# ,
I have spend all my week finding and looking for the reason why it sometimes suddenly crashing,
this console app is running continuously, no closing means when i run it it will kept running no shutting down of computer
I put every method with try catch and every catch exception it will write it to the logs
but when the application crashed there's no logs so that means there's exception that not being handled
can some one help find the possible reason why.
I'm drop off the whole code here.
class Program
{
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
protected static string server_hostname = ConfigurationManager.AppSettings["ServerHostname"];
protected static string copychimp_server = "";
protected static int port_number = 0;
private static byte[] _buffer = new byte[10000];
private static List<Socket> _clientSockets = new List<Socket>();
private static Socket _serverSocket = new Socket(Dns.GetHostEntry(ConfigurationManager.AppSettings["ServerHostname"]).AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.Tcp);
private static Dictionary<string, DateTime> dict_cmd_lastsent = new Dictionary<string, DateTime>();
private static Dictionary<string, double> dict_cmd_interval = new Dictionary<string, double>();
private static Dictionary<string, string> dict_drive = new Dictionary<string, string>();
private static Dictionary<string, string> dict_host = new Dictionary<string, string>();
static bool ConsoleEventCallback(int eventType)
{
if (eventType == 2)
{
}
return false;
}
static ConsoleEventDelegate handler; // Keeps it from getting garbage collected
// Pinvoke
private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
static void Main(string[] args)
{
Console.Write(" Enter copychimp server: ");
copychimp_server = Console.ReadLine();
Console.Write("Enter port number: ");
port_number = Convert.ToInt16(Console.ReadLine());
//copychimp_server = args[0].ToString().Trim();
//port_number = Convert.ToInt16(args[1]);
//Thread.Sleep(3000);
try
{
var server_logs_dir = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\logs\\" + copychimp_server;
var server_config_dir = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\config";
var server_config = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\config\\" + copychimp_server + ".config";
if (!Directory.Exists(server_config_dir))
{
Directory.CreateDirectory(server_config_dir);
}
if (!Directory.Exists(server_logs_dir))
{
Directory.CreateDirectory(server_logs_dir);
}
var config = "";
config += "<port>" + port_number + "</port>";
config += Environment.NewLine;
try
{
var pid = GetTagValue(File.ReadAllText(server_config), "PID");
var test_pid = Process.GetProcessById(Convert.ToInt16(pid));
var pname = test_pid.ProcessName;
ServerLogs(pname + " is currently active using PID (" + pid + ")");
config += "<PID>" + pid + "</PID>";
File.WriteAllText(server_config, config);
}
catch (Exception ex)
{
config += "<PID>" + Process.GetCurrentProcess().Id + "</PID>";
File.WriteAllText(server_config, config);
handler = new ConsoleEventDelegate(ConsoleEventCallback);
const int SW_HIDE = 0;
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE); // To hide
ServerStarted();
Console.ReadKey();
}
}
catch (Exception ex)
{
ServerLogs("Main error: " + ex.Message.ToString());
}
}
private static void ServerStarted()
{
try
{
IPHostEntry hostEntry = Dns.GetHostEntry(server_hostname);
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port_number);
ServerLogs("CopyChimpServer.exe Started. Waiting for connection...");
_serverSocket.Bind(localEndPoint);
_serverSocket.Listen(1);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch (SocketException ex)
{
ServerLogs("ServerStarted Error " + ex.Message.ToString());
}
}
private static string ServerCommand(string hostname)
{
var command = "";
try
{
CopyChimpDB copychimp_db = new CopyChimpDB();
DataTable dt_robocopy = copychimp_db.GetCopyChimp("GetCommand", hostname, "");
if (dt_robocopy.Rows.Count == 1)
{
command = dt_robocopy.Rows[0]["command"].ToString();
}
else if (dt_robocopy.Rows.Count > 1)
{
ServerLogs(hostname + " GetCommand error: Returns more than 1 row.");
}
}
catch (Exception ex)
{
ServerLogs(hostname + " ServerCommand error " + ex.ToString());
}
return command;
}
private static void ReceiveCallBack(IAsyncResult AR)
{
Thread.Sleep(1000);
Socket socket = null;
string hostname = "";
string ip_address = "";
CopyChimpDB copychimp_db = new CopyChimpDB();
try
{
socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
ip_address = (socket.RemoteEndPoint as IPEndPoint).ToString().Split(':')[0];
hostname = dict_host[ip_address];
byte[] dataBuff = new byte[received];
Array.Copy(_buffer, dataBuff, received);
string message_to_client = "wait";
if (Convert.ToDouble(Math.Round((DateTime.Now - Convert.ToDateTime(dict_cmd_lastsent[hostname])).TotalMinutes, 2)) >= dict_cmd_interval[hostname])
{
var server_command = ServerCommand(hostname);
if (server_command.Trim() != "")
{
//string message_from_client = WebUtility.HtmlDecode(Encoding.ASCII.GetString(dataBuff));
message_to_client += "<DriveName>" + dict_drive[hostname] + "</DriveName>";
message_to_client += "<ServerCommand>" + ServerCommand(hostname) + "</ServerCommand>";
try
{
copychimp_db.PostCopyChimp("ConnectMachine", hostname, ip_address);
}
catch (Exception oraex)
{
ServerLogs(hostname + "--" + oraex.ToString());
}
dict_cmd_lastsent[hostname] = DateTime.Now;
//ServerLogs(hostname + " updated");
}
}
byte[] data = Encoding.ASCII.GetBytes(message_to_client);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
}
catch (SocketException ex)
{
try
{
//_clientSockets.Remove(socket);
ServerLogs(hostname + " SocketException! " + ex.Message.ToString());
if (hostname != "")
{
try
{
copychimp_db.PostCopyChimp("DisconnectMachine", hostname, ip_address);
}
catch (Exception oraex)
{
ServerLogs(hostname + "--" + oraex.ToString());
}
}
}
catch (Exception ex_)
{
ServerLogs(hostname + " DisconnectMachine error! " + ex_.ToString());
}
}
}
private static Thread thread;
private static void AcceptCallback(IAsyncResult AR)
{
string hostname = "";
try
{
CopyChimpDB copychimp_db = new CopyChimpDB();
Socket socket = _serverSocket.EndAccept(AR);
string ip_address = "";
//hostname checking
ip_address = (socket.RemoteEndPoint as IPEndPoint).ToString().Split(':')[0];
try
{
try
{
hostname = Dns.GetHostEntry(ip_address).HostName;
}
catch (Exception host_ex)
{
ServerLogs(ip_address + " GetHostEntry error: " + host_ex.Message.ToString());
DataTable dt_ip = copychimp_db.GetCopyChimp("GetHostnameByIpAddress", hostname, ip_address);
if (dt_ip.Rows.Count == 1)
{
hostname = dt_ip.Rows[0]["hostname"].ToString();
ServerLogs(ip_address + " GetHostnameByIpAddress : " + hostname);
}
}
DataTable dt_hostname = copychimp_db.GetCopyChimp("GetHostname", hostname, ip_address);
hostname = "";
if (dt_hostname.Rows.Count == 1)
{
hostname = dt_hostname.Rows[0]["hostname"].ToString();
}
else if (dt_hostname.Rows.Count > 1)
{
ServerLogs(hostname + " GetHostname error: Returns more than 1 row.");
}
if (hostname != "")
{
if (!_clientSockets.Contains(socket))
{
dict_host[ip_address] = hostname;
_clientSockets.Add(socket);
copychimp_db.PostCopyChimp("ConnectMachine", hostname, ip_address);
/*------------------------------------------------------------------------------------------------*/
dict_cmd_interval[hostname] = Convert.ToDouble(copychimp_db.GetCopyChimp("GetInterval", hostname, ip_address).Rows[0]["interval"].ToString());
/*------------------------------------------------------------------------------------------------*/
dict_cmd_lastsent[hostname] = Convert.ToDateTime(copychimp_db.GetCopyChimp("GetLastUpdate", hostname, ip_address).Rows[0]["lastupdate"]);
/*------------------------------------------------------------------------------------------------*/
dict_drive[hostname] = copychimp_db.GetCopyChimp("GetDriveName", hostname, ip_address).Rows[0]["drive_name"].ToString();
/*------------------------------------------------------------------------------------------------*/
thread = new Thread(() =>
{
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
});
thread.Start();
ServerLogs(hostname + " connected");
}
}
}
catch (Exception oraex)
{
ServerLogs(hostname + "--" + oraex.ToString());
}
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch (SocketException ex)
{
ServerLogs("AcceptCallback SocketException " + hostname + ex.Message.ToString());
}
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
}
private static void ServerLogs(string text)
{
bool logging_success = false;
try
{
string logpath = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\logs\\" + copychimp_server + "\\" + DateTime.Now.ToString("yyyyMMdd") + ".log";
do
{
try
{
string log = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]" + " " + text + Environment.NewLine;
if (!File.Exists(logpath))
{
File.WriteAllText(logpath, log);
}
else
{
File.AppendAllText(logpath, log);
}
logging_success = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
} while (logging_success == false);
}
catch (Exception ex)
{
//send emai
}
}
private static string GetTagValue(string text, string tag)
{
var result = "";
try
{
var start_tag = "<" + tag + ">";
var end_tag = "</" + tag + ">";
int pFrom = text.IndexOf(start_tag) + start_tag.Length;
int pTo = text.LastIndexOf(end_tag);
result = text.Substring(pFrom, pTo - pFrom);
}
catch (Exception ex)
{
ServerLogs("GetTagValue() error " + ex.Message.ToString());
}
return result;
}
}
A help a highly appreciated thank you in advance.
I need to log it on the DB before the crushing occurred and i'm going to use it as reference for a new automatic emailing if the app crashed.

C# UDP communication ending connection when no answer received

I'm writing simple app for dynamic communicating with arduinos over UDP.
I'm stucked during writing UDP class in C# pc app.
I have problem with ending fuction after not receiving answer from client. If I'm connecting with client which is on, there is no problem, app is runing nice and smooth after receiving answer from it.
STRING_operations str = new STRING_operations();
static int communicationPort = 8888;
string[] arduinoPool = new string[64];
private void populateArduinoPool()
{
for (int i = 0; i < 25; i++)
{
arduinoPool[i] = "192.168.1." + Convert.ToString(170 + i);
}
}
private string mainCommunication(string vIPAdsress, string Message)
{
string answer = string.Empty;
int port = communicationPort;
Console.WriteLine("IP address: " + vIPAdsress);
Console.WriteLine("Message to sent: " + Message);
Byte[] sendBytes = Encoding.ASCII.GetBytes(str.sendString(Message));
Byte[] receiveBytes = null;
var IP = IPAddress.Parse(vIPAdsress);
var udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpClient.ReceiveTimeout = 1000;
udpClient.SendTimeout = 1000;
var sendEndPoint = new IPEndPoint(IP, port);
var receiveEndPoint = new IPEndPoint(IP, port);
var clientReturn = new UdpClient(port);
udpClient.SendTo(sendBytes, sendEndPoint);
Console.WriteLine("Message sent");
try {
receiveBytes = clientReturn.Receive(ref receiveEndPoint);
Console.WriteLine("Message is being receiving");
if (receiveBytes == null || receiveBytes.Length == 0)
{
Console.WriteLine("No answer");
;
}
Console.WriteLine(Encoding.ASCII.GetString(receiveBytes));
answer = str.trimString(Encoding.ASCII.GetString(receiveBytes));
Console.WriteLine("Trimed answer: " + answer);
udpClient.Disconnect(true);
return answer; }
catch (Exception e)
{
Console.WriteLine(e);
return e.ToString();
}
}
public void populateComboBox(ComboBox CB1)
{
Console.WriteLine("Populating arduino pool");
populateArduinoPool();
string message = str.sendString("HELLO");
for (int i = 0; i < 25; i++)
{
Console.WriteLine("Trying to communicate with: " + arduinoPool[i]);
if (mainCommunication(arduinoPool[i], message) == "YO")
{
Console.WriteLine("Established");
CB1.Items.Add(arduinoPool[i]);
}
}
}
public bool checkIfActive(ComboBox CB1)
{
string message = str.sendString("HELLO"); ;
if (mainCommunication(CB1.SelectedText.ToString(), message) == "YO")
return true;
else
return false;
}

Can a ListViewItem Tag property contain a Socket object

On my server side I have set up a single thread code that creates a new Socket object every time a client connects. Then I pass whatever I get from the client along with the socket that is connected to a packet handler and do the calculations there. In my main form I have a listview that I populate via entity framework, and whenever a packet from a registered computer connects I update the listview. So my question is can I from the packet handler class pass the socket object to the tag property of my listview when I update it?
My server side code:
private void ReceivedCallback(IAsyncResult result)
{
Socket clientSocket = result.AsyncState as Socket;
SocketError ER;
try
{
int bufferSize = clientSocket.EndReceive(result, out ER);
if (ER == SocketError.Success)
{
byte[] packet = new byte[bufferSize];
Array.Copy(_buffer, packet, packet.Length);
Console.WriteLine("Handling packet from IP:" + clientSocket.RemoteEndPoint.ToString());
//Handle packet stuff here.
PacketHandler.Handle(packet, clientSocket);
_buffer = new byte[61144];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
//clientSocket.BeginReceive(new byte[] { 0 }, 0, 0, 0, ReceivedCallback, clientSocket);
}
else
{
Console.WriteLine("No bytes received, we're closing the connection.");
clientSocket.Close();
}
}catch(SocketException ex)
{
Console.WriteLine("We caught a socket exception:" + ex.Message);
clientSocket.Close();
}
}
And my packet handler class:
public static void Handle(byte[] packet, Socket clientSocket)
{
if (clientSocket.Connected)
{
if (packet.Length > 0)
{
IPEndPoint RemoteIP = (IPEndPoint)clientSocket.RemoteEndPoint;
ushort packetLength = BitConverter.ToUInt16(packet, 0);
ushort packetType = BitConverter.ToUInt16(packet, 2);
ushort packetID = BitConverter.ToUInt16(packet, 4);
Console.WriteLine("We received a packet of Type: {0}, ID: {1} FROM {2}", packetType, packetID, RemoteIP.ToString());
if (packetType == 1)
{
switch (packetID)
{
case 1://Check if computer is registered in the database
CheckRegisteredRequest request1 = new CheckRegisteredRequest(packet);
Console.WriteLine("We received (Case 1): " + request1.Text);
string Response = "";
bool found = false;
ServerDbContext database = new ServerDbContext();
foreach (computers pcs in database.computers)
{
if (pcs.name == request1.Text.Split(',')[0])
{
found = true;
if (pcs.computer_ip == request1.Text.Split(',')[1])
{
//We found a computer with that name and ip address
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
computers registeredPC;
var name = request1.Text.Split(',')[0];
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
else
{
//We found a computer with that name but a different ip address, update it
var name = request1.Text.Split(',')[0];
var registeredPC = new computers();
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
var ip = request1.Text.Split(',')[1];
registeredPC.computer_ip = ip;
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
}
}
if (!found)
{
//There is no computer with that name in the database so send false
Response = "false";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
}
break;... and so on....
So I've tried via a handler:
this is my custom event handler Args:
public class TextArgs : EventArgs
{
#region Fields
private string szMessage;
private Socket _sockets123;
#endregion Fields
#region ConstructorsH
public TextArgs(string TextMessage,Socket sock)
{
if (sock != null)
{
_sockets123 = sock;
szMessage = TextMessage;
}
else
{
szMessage = TextMessage;
}
}
#endregion Constructors
#region Properties
public string Message
{
get { return szMessage; }
set { szMessage = value; }
}
public Socket _socket
{
get { return _sockets123; }
set { _sockets123 = value; }
}
#endregion Properties
}
This is how i define that handler at the PacketHandler class:
public static event LogsEventHandler Feedback;
private static void RaiseFeedback(string p, Socket sock)
{
LogsEventHandler handler = Feedback;
if (handler != null)
{
handler(null,new TextArgs(p,sock));
}
}
And whenever a computer registers or connects I do the following:
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], clientSocket);
or
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], null);
And the event fires of these two methods in my main form:
private void OnFeedbackReceived(object sender, TextArgs e)
{
Invoke((MethodInvoker)delegate
{
UpdateComputers();
UpdateGUI(e.Message,e._socket);
}
);
}
public void UpdateGUI(string s, Socket sock)
{
LogBox.Text += s;
LogBox.AppendText(Environment.NewLine);
using (var context = new ServerDbContext())
{
var PCInfo = context.viewUsersInfo;
dataGridView1.DataSource = PCInfo.ToList();
}
if (sock != null)
{
ListViewItem item = ComputersList.FindItemWithText(s.Split(':')[1].ToString());
item.Tag = sock;
}
}
The Question: Yes, you can. Control.Tag is of type object and can hold pretty much anything you choose.
So you can write
Socket socket = someSocket;
ListViewItem item = listView1.FindItemWithText(someText);
if (item != null) item.Tag = socket; else Console.WriteLine(someText + " not found!);
And retrieve it as:
if (item.Tag != null) someSocket = item.Tag AS socket;
if (someSocket != null) ..
It is up to you to watch out for the success of the cast when retrieving it but also if the Socket still is alive and well..
The problem: The stackoverflow in your code is due to an erreanous, short-circuited property, which you have fixed by now. In general, you only need to write explicit getter and setters if they actually do more than just gettin and setting.
They could log out out test data, update other, dependent properties, do checks or conversiones or do other stuff.
But if none of it is needed, simply don't create the private fields and write the automatic getter and setters:
public Socket MySocket {get; set;}
Also note that the naming convention asks you to capitalize proprety names!

telnet connection to a c# socket doesn't close

I have a c# socket based server which serves TCP clients.
I use telnet based monitoring to see if the server is listening.
to versify clients are up i use server keep alive (sending a random string data), and if socket expection raises-i remove the client from a client's dictionary.
the probelm is: the telnet connections to the socket doesn't get removed from the list of connections and the number of clients is rising up slowly but surely.
i tried a telnet manually to the server through command line and than closing the telnet connection-nothing.the server just keep sending the keep alive to the telnet connection with no execptions.
this is my read call back:
protected void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the async state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.socket;
if (state.socket == null)
return;
if (!state.socket.Connected)
return;
int id = state.id;
try
{
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
string newAddedStr = string.Empty;
newAddedStr = Encoding.UTF8.GetString(state.buffer, 0, bytesRead);
//cut the new message and add it
if (state.sb == null)
state.sb = new StringBuilder();
state.sb.Append(newAddedStr);
// There might be more data, so store the data received so far.
//add data until end of XML
content = state.sb.ToString();
//IF GOT FULL MESSAGE FROM SOCKET
if ((content.Length > 0) /*&& (content.IndexOf("\0") > -1)*/)
{
String strh = String.Format("Client # {0} data: ", id);
strh += content.Replace("\0", "");
if (!strh.Contains("keepalive"))
LogWriter.Trace(strh, "");
// l(writeToGetTextBoxMsg), new object[] { strh });
if (state != null)
{
if (state.sb == null)
state.sb = new StringBuilder();
state.sb.Length = 0;
}
//add the rest of the xml
string objData = content.Replace("\0", "");
string xmlData = objData.ToString();
try
{
if (xmlData.Contains("Unsubscribe"))
{
RemoveSubscriber(xmlData);
}
else
{
if (xmlData.Contains("Subscribe"))
{
if (!state.IsInitiated)
{
state.Init();
state.socketClient.OnSocketError += new SocketErrorHandler(socketClient_OnSocketError);
state.socketClient.clientSocket = handler;
}
AddSubscriber(xmlData, state);
}
}
xmlData = null;
objData = null;
content = null;
}
catch (ArgumentOutOfRangeException ex)
{
LogWriter.Trace(newAddedStr,"ArgumentOutOfRangeException in ReadCallback");
}
catch (Exception ex)
{
LogWriter.TraceError(ex.Message + " " + ex.StackTrace + " " + newAddedStr);
}
#region oldCode
#endregion
}
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(this.ReadCallback), state);
}
}
catch (System.Net.Sockets.SocketException es)
{
closeSocket(state, false, "Execption:" + es.Message + "," + es.StackTrace);
if (es.ErrorCode != 64)
{
LogWriter.Trace(string.Format("Socket Exception: {0}, {1}.", es.ErrorCode, es.ToString()), "");
}
}
catch (Exception e)
{
closeSocket(state, false,"Execption:"+e.Message+","+e.StackTrace);
if (e.GetType().FullName != "System.ObjectDisposedException")
{
Console.WriteLine("Exception: " + e.StackTrace);
LogWriter.Trace("Exception Message: " + e.ToString() + e.StackTrace, "");
Console.WriteLine("Exception Message: " + e.ToString());
LogWriter.Trace("ReadCallback:" + e.Message + " " + e.StackTrace, "ERROR");
}
}
}
any ideas?
When you do a read of a socket and 0 is returned you know that the other side of the connection has closed. Are you doing that?

Categories