I am trying to create a GUI to an ESP8266 project that I have already developed. The boards are using the NodeMCU firmware, and I am loading programs on through the ESP8266 Arduino Core. I am using C# for my GUI program on Windows.
Here is my debug code for the ESP8266 (in Arduino):
#include <ESP8266WiFi.h>
String ConnectedMAC[8];
IPAddress ConnectedIP[8];
WiFiClient clientforcom;
void setup() {
WiFi.mode(WIFI_AP_STA);
Serial.begin(9600);
int f = WiFi.scanNetworks();
Serial.println("Scanning Networks");
delay(5000);
for (int n = 0; n < f; n++) {
Serial.println(WiFi.SSID(n));
}
WiFi.begin(ssid, passtring); //SSID and passtring are my home network credentials
delay(2000);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.print("The IP of this node is: ");
Serial.println(WiFi.localIP());
}
void loop() {
MACManagement();
WiFiServer serverforclient(WiFi.localIP(), 25565);
while (!serverforclient.hasClient()) { //this does not work with Socket or delay is too long
delay(50);
Serial.println("Waiting for client");
}
clientforcom = serverforclient.available();
while (clientforcom.available() <= 0) {
delay(50);
Serial.println("Waiting for response");
}
String response = clientforcom.readString();
if (response.startsWith("GetController")) {
Serial.println("Sending String");
clientforcom.println("Returned String");
}
}
void MACManagement() {
unsigned char number_client;
struct station_info *stat_info;
struct ip_addr *IPaddress;
IPAddress address;
int i = 0;
number_client = wifi_softap_get_station_num();
stat_info = wifi_softap_get_station_info();
Serial.print(" Total Connected Clients are = ");
Serial.println(number_client);
while (stat_info != NULL) {
IPaddress = &stat_info->ip;
address = IPaddress->addr;
Serial.print("client= ");
Serial.print(i);
Serial.print(" IP adress is = ");
Serial.print((address));
ConnectedIP[i] = address;
Serial.print(" with MAC adress is = ");
Serial.print(stat_info->bssid[0], HEX); Serial.print(" ");
Serial.print(stat_info->bssid[1], HEX); Serial.print(" ");
Serial.print(stat_info->bssid[2], HEX); Serial.print(" ");
Serial.print(stat_info->bssid[3], HEX); Serial.print(" ");
Serial.print(stat_info->bssid[4], HEX); Serial.print(" ");
Serial.print(stat_info->bssid[5], HEX); Serial.print(" ");
ConnectedMAC[i] = String(stat_info->bssid[0], HEX) + ":" + String(stat_info->bssid[1], HEX) + ":" + String(stat_info->bssid[2], HEX) + ":" + String(stat_info->bssid[3], HEX) + ":" + String(stat_info->bssid[4], HEX) + ":" + String(stat_info->bssid[5], HEX);
stat_info = STAILQ_NEXT(stat_info, next);
i++;
Serial.println();
}
}
and here is my network accessing code in C#:
void loadUI(){
enterIPLabel.Visible=false;
errorBox.Text="Connecting to Leader node";
tcpcom=new TcpClient(leadernode.ToString(),25565);
tcpcom.Connect(leadernode.ToString(),25565);
while(!tcpcom.Connected);
tcpcom.Client.Send(System.Text.Encoding.ASCII.GetBytes("GetController"));
errorBox.Text="Awaiting Node Response";
while(tcpcom.Available<=0); //hopefully this should stop this method from executing until the response is made
//FILL IN CODE FOR RETURN STATEMENT
tabController.Visible=true;
NodeMap.Visible=true;
}
However, when I reach the "Waiting for Client" section of the ESP8266 code and I run the C# program, entering the IP Address into leadernode. I get an error from .NET that states:
System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
I have no idea why the ESP8266 would be refusing the connection, I put delays such that the Software Watch Dog would not initiate, so I don't understand why it would break the program.
Related
I stumble on the following problems:
When trying to use the Parallel Function. I need to synchronously wait until the all the information is gathered.
When I put the foreach loop inside the try there are duplicate values.
How can I fix this? I want when I scan a subnet (254 hosts) that I get live results back.
Code:
//Network Information Parallel.ForEach Example
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Text;
namespace AsteRScanneR
{
public class Program1
{
public static void Main()
{
Console.WriteLine("Enter IP Adresses seperated by a comma!");
Console.Write("Enter IP Adresses: ");
List<string> ipAdresses = new List<string>();
ipAdresses = Console.ReadLine().Split(',').ToList();
var firstOrDefault = ipAdresses.FirstOrDefault();
string[] octets = firstOrDefault.Split('.');
if (octets[3] == string.Empty)
{
ipAdresses = new List<String>();
for (int i = 1; i < 255; i++)
{
var result = String.Concat(firstOrDefault, i.ToString());
ipAdresses.Add(result);
}
}
else
{
Console.WriteLine("Multiple IP's Found!");
}
//In case you want to scan a whole subnet, user needs to input only the ABC of the IP adres and leave the D empty. It will scan 255 hosts
//Options
PingOptions pingOptions = new PingOptions(128, true);
int timeout = 1000;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
List<PingReply> pingRepliesList = new();
Parallel.ForEach(ipAdresses, ip =>
{
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = CancellationToken.None };
try
{
Stopwatch sw = new Stopwatch();
sw.Start();
Ping p = new();
lock (pingRepliesList) {
pingRepliesList.Add(p.Send(ip, timeout, buffer, pingOptions));
}
sw.Stop();
//Console.WriteLine("Pinging: "+ip+" took: "+sw.Elapsed.Milliseconds+"ms on Thread:"+ Environment.CurrentManagedThreadId);
}catch (Exception)
{
Console.WriteLine("An Error Occured...");
}
});
Console.WriteLine("");
foreach (var pingvalue in pingRepliesList)
{
if (pingvalue.Status == IPStatus.Success)
{
Console.WriteLine("Pinging " + pingvalue.Address.ToString() + " with " + pingvalue.Buffer.Length + " bytes of data:");
Console.WriteLine("Reply from " + pingvalue.Address.ToString() + ": bytes=" + pingvalue.Buffer.Length + " time" + pingvalue.RoundtripTime + "ms TTL=" + pingvalue.Options.Ttl);
Console.WriteLine("");
}
else
{
Console.WriteLine("Pinging " + pingvalue.Address.ToString() + " with " + pingvalue.Buffer.Length + " bytes of data:");
Console.WriteLine("General failure.");
Console.WriteLine("");
}
}
}
}
}
I found the solution to the problem. This is what I did:
Used the example code from: https://riptutorial.com/csharp/example/3279/parallel-for
Replacing the hard-coded list with for now the user-input. (This will be changed to args user input afterwards.)
Included the piece of code I wrote down below
Console.WriteLine("Enter IP Adresses seperated by a comma!");
Console.Write("Enter IP Adresses: ");
List<string> ipAdresses = new List<string>();
ipAdresses = Console.ReadLine().Split(',').ToList();
var firstOrDefault = ipAdresses.FirstOrDefault();
string[] octets = firstOrDefault.Split('.');
if (octets[3] == string.Empty)
{
ipAdresses = new List<String>();
for (int i = 1; i < 255; i++)
{
var result = String.Concat(firstOrDefault, i.ToString());
ipAdresses.Add(result);
}
}
else
{
Console.WriteLine("Multiple IP's Found!");
Console.WriteLine("");
}
Changed Parallel.For loop to .Count, because I am using a List
Changed some output result.Address.ToString() to ipAdresses[i] because it was creating bugs and displaying the same output over and over again.
Formatted everything in 1 string to not stumble upon problems.
I did format in 1 string on purpose, because when I formatted two strings I to get output mixed.
I've been developing a TCP server, and I require it to allow for the access of multiple clients at the same time.
I also require it to allow them to disconnect and reconnect whenever they wish and for whenever they send a TCP message for the logic to run behind it as well.
I have my basic code set up which allows for one user to be connected at once however, it doesn't allow for multiple clients.
Server Code - (First part, without logic)
IPAddress ipAd = IPAddress.Any;
TcpListener myList = new TcpListener(ipAd, 5001);
myList.Start();
Console.WriteLine("Waiting for a new connection");
Console.WriteLine("Last Connection From - " + client);
Console.Write("Stats - Errors: ");
Console.BackgroundColor = ConsoleColor.Red;
Console.Write(" " + Errors + " ");
Console.BackgroundColor = ConsoleColor.DarkCyan;
Console.WriteLine();
Console.WriteLine();
Console.Write(feed);
Socket s = myList.AcceptSocket();
client = Convert.ToString(s.RemoteEndPoint);
Console.Write(feed);
byte[] b = new byte[100];
int k = s.Receive(b);
Console.WriteLine("\n Message Recieved");
string msg = "";
for (int i = 0; i < k; i++)
{
msg = msg + Convert.ToChar(b[i]);
}
feed = feed + " \n " + msg;
There is also client code which, I'm not going to put in here because I don't believe it's needed. If you have any questions or improvements/modifications about the client just ask/tell me and I'll take a look.
I've been told there is ways of doing it through another thread but I haven't got a clue to how I would approach it.
So i am making an application which can open connections to remote devices and execute different commands. So yesterday before i left work i was debugging when i got an error. But as my application ignored it and proceeded and having not enough time to fix it immedietly i decided to do it today. When i wanted to make connection with my program again it said it couldn't authenticate (note* the parameters did not change).
So i did some checks to determine the problem, after logging in on the server and running netstat i found out that there was an active connection to port 22, which originated from my application.
Somehow the connection did not show up in my SSH manager until i rebooted it TWICE.
So to prevent things like this in a production environment, how do i prevent things like this.
my Program.cs
class Program
{
static void Main(string[] args)
{
var ip="";
var port=0;
var user="";
var pwd="";
var cmdCommand="";
ConnectionInfo ConnNfo;
ExecuteCommand exec = new ExecuteCommand();
SSHConnection sshConn = new SSHConnection();
if (args.Length > 0)
{
ip = args[0];
port = Convert.ToInt32(args[1]);
user = args[2];
pwd = args[3];
cmdCommand = args[4];
ConnNfo = sshConn.makeSSHConnection(ip, port, user, pwd);
exec.executeCMDbySSH(ConnNfo, cmdCommand);
}
else {
try
{
XMLParser parser = new XMLParser();
List<List<string>> configVars = parser.createReader("C:\\Users\\myusername\\Desktop\\config.xml");
Console.WriteLine("this is from program.cs");
//iterate through array
for (int i = 0; i < configVars[0].Count; i++)
{
if ((configVars[0][i].ToString() == "device" && configVars[1][i].ToString() == "device") && (configVars[0][i + 6].ToString() == "device" && configVars[1][i + 6].ToString() == "no value"))
{
string ipAdress = configVars[1][i + 1].ToString();
int portNum = Convert.ToInt32(configVars[1][i + 2]);
string username = configVars[1][i + 3].ToString();
string passwd = configVars[1][i + 4].ToString();
string command = configVars[1][i + 5].ToString();
Console.WriteLine("making connection with:");
Console.WriteLine(ipAdress + " " + portNum + " " + username + " " + passwd + " " + command);
ConnNfo = sshConn.makeSSHConnection(ipAdress, portNum, username, passwd);
Console.WriteLine("executing command: ");
exec.executeCMDbySSH(ConnNfo, command);
}
}
}
catch (Exception e) { Console.WriteLine("Error occurred: " + e); }
}
Console.WriteLine("press a key to exit");
Console.ReadKey();
}
}
my executeCommand class:
public class ExecuteCommand
{
public ExecuteCommand()
{
}
public void executeCMDbySSH(ConnectionInfo ConnNfo, string cmdCommand )
{
try
{
using (var sshclient = new SshClient(ConnNfo))
{
//the error appeared here at sshclient.Connect();
sshclient.Connect();
using (var cmd = sshclient.CreateCommand(cmdCommand))
{
cmd.Execute();
Console.WriteLine("Command>" + cmd.CommandText);
Console.WriteLine(cmd.Result);
Console.WriteLine("Return Value = {0}", cmd.ExitStatus);
}
sshclient.Disconnect();
}
}
catch (Exception e) { Console.WriteLine("Error occurred: " + e); }
}
}
and my class where i make conenction:
public class SSHConnection
{
public SSHConnection() { }
public ConnectionInfo makeSSHConnection(string ipAdress, int port, string user, string pwd)
{
ConnectionInfo ConnNfo = new ConnectionInfo(ipAdress, port, user,
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod(user,pwd),
}
);
return ConnNfo;
}
}
Note* i have not included my XMLParser class because it is not relevant to the question, nor does it have any connections regarding SSH in general.
EDIT
i found out i had compiled the application and it was running in the commandline. Turns out there is no error with the code
I'm trying to check if computer on the net is online by using code which supposedly to check it by using ARP packets.
I am always getting message that host is offline even when I'm sure that it's online. I have checked on my localhost IP and on some always working IPs such as google.
That could be wrong with this code?
[DllImport("iphlpapi.dll", ExactSpelling = true)]
public static extern int SendARP(IPAddress DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen);
private byte[] macAddr = new byte[6];
private uint macAddrLen;
private void Ping(IPAddress address)
{
if (SendARP(address, 0, new byte[6], ref macAddrLen) == 0)
{
open++;
txtDisplay.AppendText("Host " + address + " is open." + Environment.NewLine);
}
else
{
closed++;
txtDisplay.AppendText("Host " + address + " is closed." + Environment.NewLine);
}
}
By using previous code I'm basically trying to do something like following code. But the problem with this code is that when host is closed that it takes like 2 seconds to get the respond which I want to eliminate. Someone suggested to use ARP ping:
private void Ping(IPAddress address)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
if (cbDontFragment.Checked) options.DontFragment = true;
else options.DontFragment = false;
string dataa = string.Empty;
int dataCounter = 0;
options.Ttl = (int)nudTTL.Value;
for (int i = 0; i < nudData.Value; i++)
{
dataCounter++;
if (dataCounter == 10) dataCounter = 0;
dataa += dataCounter.ToString();
}
byte[] buffer = Encoding.ASCII.GetBytes(dataa);
int timeout = 120;
try
{
PingReply reply = pingSender.Send(address, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
open++;
txtDisplay.AppendText("Host " + address + " is open. ");
if (cbDontFragment.Checked) txtDisplay.AppendText(" Don't fragment. ");
txtDisplay.AppendText(" TTL: " + options.Ttl.ToString() + " ");
txtDisplay.AppendText(" Bytes: " + nudData.Value + " ");
txtDisplay.AppendText(Environment.NewLine);
}
else
{
closed++;
txtDisplay.AppendText("Host " + address + " is closed. ");
if (cbDontFragment.Checked) txtDisplay.AppendText(" Don't fragment. ");
txtDisplay.AppendText(" TTL: " + options.Ttl.ToString() + " ");
txtDisplay.AppendText(" Bytes: " + nudData.Value + " ");
txtDisplay.AppendText(Environment.NewLine);
}
}
catch (Exception ex)
{
txtDisplay.SelectedText += Environment.NewLine + ex.Message;
}
}
ARP cannot be used for what you are trying to do. It only works over a local network.
It's purpose is to resolve an IP address (which is routed) to a MAC address (which is not). It is never sent beyond a network segment (a lan)
I am trying to send multiple files to a server ever 2 seconds and after the file is sent it is deleted and the program is restarted as to again generate the file which needs again to be sent to server.
But it works till the time the server is online...In case the sever is restarted all the program functions will work fine but when this function is invoked it keeps on displaying "No connection could be made because the target machine actively refused it" no matter even when the server comes online in between..
private void sendfile()
{
timer.Stop();
RegistryKey theLocalMachine = Registry.LocalMachine;
RegistryKey theSystem2 = theLocalMachine.OpenSubKey(#"SOFTWARE\\NetworkUsagemonitoring\\", true);
RegistryKey interfacekey4 = theSystem2.OpenSubKey("Usagerecorder", true);
string serverno = interfacekey4.GetValue("serverno").ToString();
for (int i = 0; i < netarr1.Length; i++)
{
for (int j = 0; j < netarr2.Length; j++)
{
if (netarr1[i].Name == netarr2[j])
{
if (recorded[j] == 1)
{
try
{
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(serverno), 5656);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
if (File.Exists(#"C:\" + netarr1[i].Name + "_record.xml"))
{
fileName = (#"C:\" + netarr1[i].Name + "_record.xml");
fileName = fileName.Replace("\\", "/");
while (fileName.IndexOf("/") > -1)
{
filePath += fileName.Substring(0, fileName.IndexOf("/") + 1);
fileName = fileName.Substring(fileName.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
if (fileNameByte.Length > 850 * 1024)
{
return;
}
byte[] fileData = File.ReadAllBytes(filePath + fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
clientSock.Connect(ipEnd);
clientSock.Send(clientData);
clientSock.Close();
recorded[j] = 0;
File.Delete(#"C:\" + netarr1[i].Name + "_record.xml");
}
else
{
UpdateNetwork_Interface();
}
}
catch (Exception ex)
{
LogEvent("No connection could be made because the target machine actively refused it", EventLogEntryType.Information);
break;
}
finally
{
j++;
}
}
else
{
UpdateNetwork_Interface();
}
}
}
}
}
What i want is of the server goes offline or "No connection could be made because the target machine actively refused it" is displayed...the program should continue with the loop and move unhindered until server comes online and the updated file will be sent to the server.
Well, you're exception handling is faulty. You are catching (Exception ex) and printing out the error message you quoted. It's entirely possible that the ACTUALL exception has to do with the files you are writing and erasing. perhaps some files failed to erase or be opened.
Looking at the code, i suspect the problem is that you're never actually closing the socket if there is an exception.
You should add the following to the finally clause.
if (clientSocket!=null)
clientSocket.Close();
And you should print out the actual exception message to the error log so you know what's really going on when an error occurs.