So today I was messing around with some IP protection for a program I am making.
The whitelist for IPs is hosted on pastebin.
My program downloads the IPs, splits it into an array of strings.
My program also checks the ip using https://wtfismyip.com/text
What I want to do is compare each string from the array and check if it is the current IP.
If the IP is not the current IP by the end, then it will close.
How would I do this?
Example of the code:
for (int i = 0; i < iplist.Length; i++)
{
if(iplist[i] == WebIP)
{
MessageBox.Show("Passed");
}
else
{
this.Close();
}
}
You can use some LINQ to make the code more readable:
if (iplist.Any(ip => ip == WebIP))
{
MessageBox.Show("Passed");
}
else
{
this.Close();
}
assuming you're going to test lots of times, create a HashSet<T> of the whitelist (or similarly: blacklist); assuming it is a string:
var whiteList = new HashSet<string>(iplist);
(do this once, not every time you need to check)
then just check .Contains:
bool isOK = whiteList.Contains(WebIP);
job done, and very efficiently
You can have a flag and set it accordingly like
bool flag = false;
for (int i = 0; i < iplist.Length; i++)
{
if(iplist[i] == WebIP)
{
flag = true;
break;
}
}
if(flag)
MessageBox.Show("Passed");
else
this.Close();
Related
Below is a button, when pressed it calls a function that pings a bunch of IP addresses. If the IP address returns a response, it adds the IP address to the output_networkSearch.Text.
private void button_networkSearch_Click(object sender, RoutedEventArgs e)
{
output_networkSearch.Text = networkSearch(Convert.ToInt32(input_searchLimit.Text));
}
Below isn't the whole method, just the part that I can't get to work. The for loop starts at whatever the last digit on the users default gateway IP address is, and stops at whatever limit they have inputed (1 - 255).
// i is equal to the last digit in the default gateway IP, if it was 192.168.0.1 then i = 1.
for (int i = Convert.ToInt32(splitGatewayIP[3]); i <= searchLimit; i = i + 1)
{
// If the method receieves a ping reply...
if (PingHostSweep(gatewayIPRebuild + i))
{
// Returns 192.168.0. + i + ACTIVE
string response = gatewayIPRebuild + i + " ACTIVE";
return response;
}
else
{
string response = gatewayIPRebuild + i + " CLOSED";
return response;
}
}
This worked on a console application but for a WPF application it seems to run through the loop once and stop due to the return statement.
My idea to work around this would be to remove the Return Response statements and try and access the TextBox (output_networkSearch) directly.
So I would do something like:
for (int i = Convert.ToInt32(splitGatewayIP[3]); i <= searchLimit; i = i + 1)
{
// If the method receieves a ping reply...
if (PingHostSweep(gatewayIPRebuild + i))
{
// Returns 192.168.0. + i + ACTIVE
string response = gatewayIPRebuild + i + " ACTIVE";
output_networkSearch.Text = reponse;
}
else
{
string response = gatewayIPRebuild + i + " CLOSED";
output_networkSearch.Text = reponse;
}
}
HOWEVER, I can't access the textbox within the method for some reason. I've only just started learning C# so I'm not entirely familiar with how it works.
Here's an image of a partially working concept. As you can see the limit is set at 10, so it should ping IP address 1 through 10 and give an ACTIVE or CLOSED response. This did work in my console application version.
WPF version
Console version
This might do the trick for you
List<string> responses = new List<string>();
string response;
for (int i = Convert.ToInt32(splitGatewayIP[3]); i <= searchLimit; i = i + 1)
{
if (PingHostSweep(gatewayIPRebuild + i))
{
response = gatewayIPRebuild + i + " ACTIVE";
}
else
{
response = gatewayIPRebuild + i + " CLOSED";
}
responses.Add(response)
}
Now after the loop the list which is responses would have the list of all the IPs which are active and closed. Like the way you do had in the console Application.
i think you need use threading, there are need many child threading work in backend to scan, when they finish them work then response the result to MainForm, so i write some code hope can help you!
using System.Threading;
using System.Threading.Tasks;
public void Start(string ip)
{
Task.Factory.StartNew(() =>
{
// If the method receieves a ping reply...
string response;
if (PingHostSweep(ip))
{
// Returns 192.168.0. + i + ACTIVE
response = ip + " ACTIVE";
}
else
{
response = ip + " CLOSED";
}
this.Invoke((MethodInvoker)(() => { textBox1.AppendText("\r\n" + response); }));
});
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 255; i++)
{
Start(String.Format("192.168.100.{0}", i));
}
}
The previous answer was correct (though it didn't touch on a more advanced point that you will ultimately need to learn ... delegation and invocation ... long story ... won't bore you now).
What you wrote distills to this:
// SIDE NOTE: you cannot actually treat an IPv4 address as four "pure" quads (but that's not your question)
var notNecessarilyAHost = splitGatewayIP[3];
var searchStart = Convert.ToInt32(notNecessarilyAHost);
for (var i = searchStart; i <= searchLimit; ++i)
{
if (PingHostSweep(gatewayIPRebuild + i))
{
return $"{gatewayIPRebuild}{i} ACTIVE";
}
else
{
return $"{gatewayIPRebuild}{i} CLOSED";
}
}
...and if you (mentally) step through what you wrote it's fairly straightforward to see that the loop will only ever cycle once. Upon entry to the loop i will be equal to whatever searchStart is. Then you enter the if test. If that test is true, you fall into the true side of the branch (i.e., "...ACTIVE"). Otherwise, you'll drop into the else branch (i.e., "...CLOSED". FROM THERE...
You ALWAYS return. That will exit the loop (and the function that contains it). You will never cycle the loop again. "break" and "return" (and plausibly goto ... but that's for a different day) will ALWAYS exit the current scope (scope being a block of code wrapped by '{' and '}' (be they explicitly or implicitly written).
Following?
The previous answer was correct. It adjusts your code so that the loop adds the string you're composing with each iteration to a list of strings. Then, when you exit the loop (because i reaches searchLimit) that list of strings will contain N many, well, strings. You probably want to return or continue working that.
All that said, you can't (technically you can but you SHOULDN'T) do any of this inside a UI thread. If you do, the UI will block (and become 100% unresponsive to the user) while the loop runs (and the network calls that it makes run), etc.
I have a loop that is running every 10 seconds that does a few things. One thing it does is it enables a button when there is a message that I am sending to the users of the app. I want to send a notification to the system tray when that button enables, but for obvious reasons I only want that notification triggered once when the user has an unread broadcast.
Here is the code I have:
private void EnableBroadcasts()
{
string query = "SELECT COUNT(*) FROM db.broadcasts WHERE broadcast_active = '1'";
int count = StoredProcedures.CountRecordsT4(query);
StreamReader re = new StreamReader(#"C:\\Users\\" + Environment.UserName + #"\\appdata\\Local\\Cache\\broadcasts.cache");
List<string> ReadBroadcastList = new List<string>();
List<string> BcastID = BroadcastID();
if (BroadcastCount != count)
{
string text = re.ReadToEnd();
re.Close();
string[] lines = text.Split('\r');
foreach (string s in lines)
{
ReadBroadcastList.Add(s);
}
for (int t = 0; t < ReadBroadcastList.Count(); t++)
{
ReadBroadcastList[t] = ReadBroadcastList[t].Trim('\n');
}
ReadBroadcastList.Remove("");
BroadcastCount = ReadBroadcastList.Count();
}
var test = BcastID.Except(ReadBroadcastList).ToList();
int read = test.Count();
if (count != 0)
{
btnWESBroadcast.Visible = true;
}
else
{
btnWESBroadcast.Visible = false;
}
The button enables once count is not zero. I have a list of broadcast ID's that are active from the db,I also have a cache file that records what broadcast ID's that user has read.
I am looking for a solution that will have the notification only run when the button is active and there is a broadcast that the user has not read.
Wrap your string broadcast in a simple type: BroadcastMessage. Add a bool IsRead flag.
Mark IsRead = true and the message will be ignored with the following logic.
// pseudo
if (button.IsEnabled && ReadBroadcastList.Any(msg => !msg.IsRead)) {
NotifyTray();
}
Then you can later add a feature for the user to mark a message Unread.
If you intend to persist this data in the database, then both the message and flag can be stored in the BroadcastMessage object. When a user reads the message and the object is marked as read, update the database with the change.
Update: based on clarification in comment
Add a bool IsNotified flag to the BroadcastMessage notification and check !msg.IsNotified instead of !msg.IsRead.
I have an program in production environment where I like to have a window to open, when a remote assistance are started on the pc, so the person connecting to the pc have some more options. But i can't find anything if this is possible? If so any idea how to detect it?
This can be done but I find it tricky and I generally avoid this. See How to detect RDC from C#.net for more info.
To start RDP listens on port 3389 so something like this should work.
int port = 3389;
using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp", false))
{
if (key != null)
{
object value = key.GetValue("PortNumber");
if (value != null) port = Convert.ToInt32(value);
}
}
But the port number can be configured so this isn't the best way.
Then there is Pinvoke and Cassia. with Cassia you could do something like:
public bool IsComputerUsedByTS()
{
var tsMgr = new TerminalServicesManager();
var localSvr = tsMgr.GetLocalServer();
var sessions = localSvr.GetSessions();
foreach(var session in sessions)
{
if(session.ConnectionState == ConnectionState.Active ||
session.ConnectionState == ConnectionState.Connected) //Add more states you want to check for as needed
{
return true;
}
}
return false;
}
And last but not least:
System.Windows.Forms.SystemInformation.TerminalServerSession
This uses a forms import but is a very simple solution. If you run your program in a remote desktop environment, this returns true.
I have a situation where I read values from sensors (attached to an arduino) which gets stored in a mysql database, which is then displayed on a webpage. At the same time relay values are read from a webpage, stored on mysql and then written to the arduino. I can do each separately but not at the same time. I've attached some code to show what Im trying to accomplish. I think it has something to do with Serial availability
/*----( SETUP: RUNS ONCE )----*/
void setup() {
Serial.begin(115200);
sensors.begin(); //Get DS18B20 temperatures
sensors.setResolution(probe1, 10); //set resolution to 10bit
sensors.setResolution(probe2, 10); //set resolution to 10bit
Wire.begin(); // Start the Wire (I2C communications)
RTC.begin(); // Start the RTC Chip
digitalWrite(Relay_1, RELAY_OFF); //Relays
digitalWrite(Relay_2, RELAY_OFF);
pinMode(Relay_1, OUTPUT); //Set relays as outputs
pinMode(Relay_2, OUTPUT);
}
/*--(end setup )---*/
/****** LOOP: RUNS CONSTANTLY ******/
void loop() {
ReadSensors();
delay(1000);
ReadRelays();
}
/****** Read Sensors ******/
void ReadSensors()
{
DateTime now = RTC.now(); //Get time from RTC
photolevel = analogRead(photopin); //Read light level
sensors.requestTemperatures();
dallas1 = sensors.getTempC(probe1);
dallas2 = sensors.getTempC(probe2);
dtostrf(photolevel, 1, 0, photo1);
dtostrf(dallas1, 1, 2, temp1);
dtostrf(dallas2, 1, 2, temp2);
String tempAsString1 = String(photo1);
String tempAsString2 = String(temp1);
String tempAsString3 = String(temp2);
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(" ");
Serial.println(tempAsString1 + " " + tempAsString2 + " " + tempAsString3);
Serial.flush();
}
void ReadRelays()
{
Serial.flush();
// Read all serial data available, as fast as possible
while(Serial.available() > 0)
{
char inChar = Serial.read();
if(inChar == SOP)
{
index = 0;
inData[index] = '\0';
started = true;
ended = false;
}
else if(inChar == EOP)
{
ended = true;
break;
}
else
{
if(index < 79)
{
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
if(started && ended)
{
// The end of packet marker arrived. Process the packet
if (strlen(inData) > 0)
{
char *token = strtok(inData, ",");
if(token)
{
index = 0;
array[index] = atoi(token);
while (token = strtok(NULL, ","))
{
array[index++] = atoi(token);
}
}
}
Serial.println(array[0]);
Serial.println(array[1]);
// Reset for the next packet
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
}
Any suggestions would be well appreciated??
The key to do several things "at the same time" is to understand that the Arduino has only one core. Thus it will process stuff only one step after the other. Now suppose you want to perform three functions "action1()", "action2()" and "action3()" at "the same time. In order to achieve this you must ensure that
all actions can be performed as fast as possible, preferably sub milliseconds
none of them "blocks"
Then the desired effect is achieved by just putting them into succession like so
void loop() {
action1();
action2();
action3();
}
This is the basic idea of "cooperative multitasking". It follows that none of the actions must utilize delay() or blocking waits. For example
while(Serial.available() == 0);
is a blocking wait and must be avoided. Things get more complicated if any of the actions is a set of lengthy and involved computations. Say action1() takes 1s to process. Then action1() must be split into pieces that execute fast enough. The pieces can still be kept in action1() with the help of a "state machine". For example
void action1() {
static uint8_t state = 0;
switch (state) {
case 1: sub_action1_1(); break;
case 2: sub_action1_2(); break;
case 3: sub_action1_2(); break;
default: state = 0; return;
}
++state;
}
Of course the sub actions must perform fast enough. Another frequently encountered issue is how to wait without blocking. This is achieved by storing the required delay. E.g. like this
void action1() {
static uint8_t state = 0;
static unsigned long start_millis = 0;
switch (state) {
case 1: sub_action(); break;
case 2: // this starts the delay
start_millis = millis();
break;
case 3: // this checks if the delay has elapsed
if (millis() - start_millis < 1000) {
// if it did not yet elapse ensure that the state will not progress to the next step
return;
}
// if the delay has elapsed proceed to next state
break;
case 4: next_sub_action(); break;
default: state = 0; return;
}
++state;
}
Of course this is only the basic principle. In "real" implementations you may vary this as needed.
Another often needed thing is to have a main loop that does some stuff and a higher frequency "loop" that does some other stuff. This is usually performed with so called timer interrupts. This is more advanced but usually more efficient also. The tricky thing with interrupts is that they tend to be somewhat harder to debug. I have some documented examples for this in my blog.
blinking several LEDs with different frequencies.
VU Meter experiment (scroll down!)
This is a simple .NET 4 application. Here's the code I want to run:
string username = "userfoo";
string password = "passwordfoo";
for (int i = 0; i < 2000; i++)
{
uint matchId;
if (!uint.TryParse(i.ToString(), out matchId))
{
Console.WriteLine("Invalid Match ID!");
return;
}
Client client = new Client (username, password, matchId);
// connect
client.Connect();
client.Wait();
if (client.Match != null)
{
Console.WriteLine("Inserting match: #{0}", client.Match.match_id);
Helpers.MatchHelper.AddMatchToDatabase(client.Match);
}
else
{
Console.WriteLine("Couldn't get match: #{0}", 1);
}
}
Instead doing this one by one (it would take forever - 415 days nonstop according to my calculations), what's the easiest way to invoke each iteration of this for loop asynchronously?
Most questions and articles are very old (circa 2001!) surely there must be a more modern approach?
http://msdn.microsoft.com/en-us/magazine/cc301332.aspx
You can find information here: http://msdn.microsoft.com/en-us/library/ff963552.aspx. Basically, you just use Parallel.For(0, n, x => doSomething). That takes care of parallelization. This is a functionality of PLINQ that is extremely easy to use an in my experience works quite well.
Your sample would look like this:
string username = "userfoo";
string password = "passwordfoo";
Parallel.For(0, 2000, i =>
{
uint matchId;
if (!uint.TryParse(i.ToString(), out matchId))
{
Console.WriteLine("Invalid Match ID!");
return;
}
Client client = new Client (username, password, matchId);
// connect
client.Connect();
client.Wait();
if (client.Match != null)
{
Console.WriteLine("Inserting match: #{0}", client.Match.match_id);
Helpers.MatchHelper.AddMatchToDatabase(client.Match);
}
else
{
Console.WriteLine("Couldn't get match: #{0}", 1);
}
});
I think this is what you are looking for:
http://www.codeproject.com/Articles/71285/Introducing-NET-4-0-Parallel-Programming
You should look at the task parallel library
If i understand you correctly, you want to run these in a separate thread. Here's one way to do this:
You need to move the code from the loop into a void function:
void MyThreadInsteadOfLoop(object parameter)
{
int i = (int)parameter;
uint matchId;
if (!uint.TryParse(i.ToString(), out matchId))
{
Console.WriteLine("Invalid Match ID!");
return;
}
Client client = new Client (username, password, matchId);
// connect
client.Connect();
client.Wait();
if (client.Match != null)
{
Console.WriteLine("Inserting match: #{0}", client.Match.match_id);
Helpers.MatchHelper.AddMatchToDatabase(client.Match);
}
else
{
Console.WriteLine("Couldn't get match: #{0}", 1);
}
}
In your main thread, you need to prepare threads to run, start them, and wait them to finish, if you want to. Here's the code:
//Create threads
List<Thread> threads = new List<Thread>();
for(int i=0;i<2000;i++)
{
threads.Add(new Thread(new ParameterizedThreadStart(MyThreadInsteadOfLoop)));
}
//Start threads
int x = 0;
foreach(var t in threads)
{
t.Start(x);
x++;
}
//wait for the threads to finish
foreach(var t in threads)
{
t.Join();
}
Be aware, that you have to make the MatchHelper class, and other classes that exchange data with your threads thread safe, and that tends to add lots of overhead to your program. Also, you can possibly run into trouble with the network connections.
Only [NumberOfCpuCores]*2 threads will actively work (*2 because of hyper-threading) at a time, but since you have to wait for the client (I really hope that's not a while(true) cycle cloaked) that might get concealed at least partly.