I have a problem with my code, it works really slow
My Code:
private static void PortRangeScan()
{
Console.Clear();
var From = FROM.Split('.'); // example (103.218.27.85)
string From1 = From[0];
string From2 = From[1];
string From3 = From[2];
string From4 = From[3];
var To = TO.Split('.'); // example (123.218.27.85)
string To1 = To[0];
string To2 = To[1];
string To3 = To[2];
string To4 = To[3];
for (int CurrentProxy = int.Parse(From1); CurrentProxy <= int.Parse(To1); CurrentProxy++)
{
foreach (int s in Ports)
{
TcpClient Scan = new TcpClient();
try
{
// If there is no exception then the Port is open
Scan.Connect($"{CurrentProxy}.{From2}.{From3}.{From4}", s);
Console.WriteLine($"[{CurrentProxy}.{From2}.{From3}.{From4}] | [{s}] | OPEN", Color.Green);
}
catch
{
// If there is an excpetion then it means the Port is closed
Console.WriteLine($"[{CurrentProxy}.{From2}.{From3}.{From4}] | [{s}] | CLOSED", Color.Red);
}
}
}
}
this code works really slow, if the port is closed, it can take up to 10 seconds until it checks the next port.
I wanted to add a Parallel.For loop or multi-threading but I am not sure how I can do it with this code.
so what do I need:
how can I make this code much faster or how can I add multi-threading
You could use the System.Net.Network Information namespace. Specifically the IPGlobal properties class. It can be used to return a full list of the currently used ports.
Sorry for the formatting. I am on mobile, but here is an example.
var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
var tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
foreach (var tcpi in tcpConnInfoArray)
{
Console.Write($"Port {tcpi.LocalEndPoint.Port} is in use.");
}
Related
Im stuck. I have joined the project that uses Named Pipes, and have lets say "not ideal architecture". And seems like I accidentally received a deadlock:(
The logic is following. There is Named Pipe. Client and Server model. On server part there is a loop, that always pings named pipe and process what client sends, sometimes sending back responses.
On Client side of my pipe, I have following method, from other developer, that is being used to send request to server and receive and return the response.
private object locker = new Object();
private string ListenOnce(string msg)
{
Debug.WriteLine("Will listen for message " + msg);
string msgFrom = "";
if (run) {
string toReturn = "";
lock (locker) {
sw.WriteLine(msg); //Writing command to the pipes
stream.WaitForPipeDrain(); //Waiting for another process to read the command
msgFrom = sr.ReadLine(); //Reading
toReturn = sr.ReadLine ();
if (toReturn.Contains('¥'))
{
string[] split = toReturn.Split('¥');
if (split.Length > 1)
{
var roomNames = this.connection.application.GameCache.GetRoomNames();
for (int i = 1; i < split.Length; i++)
{
string[] split2 = split[i].Split('¶');
if (split2.Length > 1)
{
string accountName = split2[0];
int offenderActorID = int.Parse(split2[1]);
string offenderRoomName = split2[2];
foreach (var roomName in roomNames)
{
Room room;
if (this.connection.application.GameCache.TryGetRoomWithoutReference(roomName, out room))
{
Game game = room as Game;
if (game != null && game.Name == offenderRoomName)
{
GameClientPeer peer = (GameClientPeer)game.ActorsManager.ActorsGetActorByNumber(offenderActorID).Peer;
if (peer != null)
{
peer.KickPlayer();
}
}
}
}
}
}
}
}
}
if (toReturn.Contains('¥'))
{
return toReturn.Split('¥')[0];
}
else
{
return toReturn;
}
}
return "";
}
The problem is - in some cases I cant receive response from pipe right when requested, and need to start what I called here "poller". This is a task, that loops 5 times, and during those 5 times "polls" the pipe through this ListenOnce method.
private void PollTargets()
{
timer.Dispose();
Debug.WriteLine("Going to start polling");
Task.Factory.StartNew(() => {
int runCount = 0;
while (true)
{
runCount++;
PipeOperation request = new PipeOperation(Consts.Pipes.RequestTargets, uniqueID);
string responseStr = unityConnection.client.SendMessage(JsonConvert.SerializeObject(request));
Debug.WriteLine("Task is running, response is " + responseStr);
if (!string.IsNullOrEmpty(responseStr))
{
try
{
PipeOperation pipeResponse = JsonConvert.DeserializeObject<PipeOperation>(responseStr);
if (!string.IsNullOrEmpty(pipeResponse.Payload))
{
GrenadeExplosionData explosionData = JsonConvert.DeserializeObject<GrenadeExplosionData>(pipeResponse.Payload);
if (explosionData != null)
{
//probably need to invoke that in main thread
DealDamage(explosionData);
//isRunning = false;
Debug.WriteLine("Received nice response, will damage targets");
break;
}
}
}
catch (Exception exc)
{
Debug.WriteLine("Something went wrong while polling...");
Debug.WriteLine(exc.Message);
break;
}
}
if (runCount > 5)
{
Debug.WriteLine("run count exceed " + runCount.ToString());
break;
}
}
RemoveGrenadeFromUnityConnection();
});
}
I am starting poller when the Grenade explodes, from timer like that:
timer = new System.Threading.Timer((obj) =>
{
PollTargets();
},
null, 4000, System.Threading.Timeout.Infinite);
And thats it. After people play 2-3 hrs. Seems like I receive a deadlock. It should be taken into account that there might be many grenades on server who starts that poller, so probably it just goes mad at some point over there.
Pls help, Im stuck with that. Who has ideas?
We should keep in mind, that
sw.WriteLine(msg); //Writing command to the pipes
stream.WaitForPipeDrain();
msgFrom = sr.ReadLine(); //Reading
toReturn = sr.ReadLine ();
should be used only by one thread at a time, as stream might be read only from one source.
There are several calls to ListenOnce from the code, but not a lot. One is being fired every 4 minutes.The rest ones are not constant, but conditional.
Hope somebody would see where is a mistake here...
Found what locks everything...However, it does not help a lot:)
Its
stream.WaitForPipeDrain();
it tries to read another end of pipe, but because of there is no timeouts in message mode, it just hangs for ever..
I am fairly new to ZeroMQ and have been comparing security of messages using the ZeroMQ NuGet package and the NetMQ & NetMQ Security NuGet packages.
So far, I have not been able to find a C# version of the Ironhouse example using Curve Security. There is a "todo" item on the ZGuides repo but so far nothing implemented. (https://github.com/metadings/zguide/issues/1)
I am also trying to determine whether the NetMQ.Security approach to security is better than the curve security approach that is built into ZeroMQ 4. It seems like most information about Curve is at least from 2014 or earlier.
Any information would be greatly appreciated!
Both publisher and subscriber need to use its own set of public\private keys. In your sample code for subscriber you set CurvePublicKey (to that of server, which is wrong but still) but do not set CurveSecretKey - that's why you get "cannot open client INITIATE vouch". Here is your sample from another question fixed:
public class Program
{
static void Main(string[] args) {
using (var context = new ZContext()) {
Console.WriteLine($"Curve Supported: {ZeroMQ.ZContext.Has("curve")}");
byte[] serverPublicKey;
byte[] serverSecretKey;
Z85.CurveKeypair(out serverPublicKey, out serverSecretKey);
var publisher = new ZSocket(context, ZSocketType.PUB);
publisher.CurvePublicKey = serverPublicKey;
publisher.CurveSecretKey = serverSecretKey;
publisher.CurveServer = true;
publisher.Bind("tcp://*:5050");
var subscriber = new ZSocket(context, ZSocketType.SUB);
byte[] subPublicKey;
byte[] subSecretKey;
Z85.CurveKeypair(out subPublicKey, out subSecretKey);
subscriber.CurvePublicKey = subPublicKey;
subscriber.CurveSecretKey = subSecretKey;
subscriber.CurveServerKey = serverPublicKey;
ZError connectError;
subscriber.Connect("tcp://mybox:5050", out connectError);
if (connectError != null) {
Console.WriteLine($"Connection error: {connectError.Name} - {connectError.Number} - {connectError.Text}");
}
subscriber.SubscribeAll();
// Publish some messages
Task.Run(() => {
for (var i = 1; i <= 5; i++) {
var msg = $"Pub msg: {Guid.NewGuid().ToString()}";
using (var frame = new ZFrame(msg)) {
publisher.Send(frame);
}
}
});
Task.Run(() => {
// Receive some messages
while (true) {
using (var frame = subscriber.ReceiveFrame()) {
var msg = frame.ReadString();
Console.WriteLine($"Received: {msg}");
}
}
});
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
ZError subError;
subscriber.Disconnect("tcp://mybox:5050", out subError);
subscriber.Dispose();
ZError pubError;
publisher.Disconnect("tcp://*:5050", out pubError);
publisher.Dispose();
}
}
}
Indeed, there are not much C# examples with NetMQ. I found this that works "CurveTests.cs":
public void CurveTest()
{
var serverPair = new NetMQCertificate();
using var server = new DealerSocket();
server.Options.CurveServer = true;
server.Options.CurveCertificate = serverPair;
server.Bind($"tcp://127.0.0.1:55367");
var clientPair = new NetMQCertificate();
using var client = new DealerSocket();
client.Options.CurveServerKey = serverPair.PublicKey;
client.Options.CurveCertificate = clientPair;
client.Connect("tcp://127.0.0.1:55367");
for (int i = 0; i < 100; i++)
{
client.SendFrame("Hello");
var hello = server.ReceiveFrameString();
Assert.Equal("Hello", hello);
server.SendFrame("World");
var world = client.ReceiveFrameString();
Assert.Equal("World", world);
}
}
Important note - if you want to share server public key between different applications, don't use string representation (serverPair.PublicKeyZ85), because encryption won't work. I assume it related to encoding. Better save byte array representation to some file and share it instead:
File.WriteAllBytes("serverPublicKey.txt", serverPair.PublicKey);
I've been trying to find a way to figure out which installed printers are 'connected'. After some Googling I figured I had to dive into WMI.
So I've built this test:
// Struct to store printer data in.
public struct MyPrinter
{
public string Availability;
public string ExtendedPrinterStatus;
public string Name;
public string PrinterStatus;
public string Status;
public string StatusInfo;
public MyPrinter(string a, string eps, string n, string ps, string s, string si)
{
Availability = a;
ExtendedPrinterStatus = eps;
Name = n;
PrinterStatus = ps;
Status = s;
StatusInfo = si;
}
}
var installedPrinters = new string[numPrinters];
PrinterSettings.InstalledPrinters.CopyTo(installedPrinters, 0);
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
var data = new List<MyPrinter>();
foreach (var printer in searcher.Get())
{
if (installedPrinters.Contains(printer["Name"].ToString()))
{
var availability = (printer["Availability"] ?? "").ToString();
var extendedPrinterStatus = (printer["ExtendedPrinterStatus"] ?? "").ToString();
var name = (printer["Name"] ?? "").ToString();
var printerStatus = (printer["PrinterStatus"] ?? "").ToString();
var status = (printer["Status"] ?? "").ToString();
var statusInfo = (printer["StatusInfo"] ?? "").ToString();
data.Add(new MyPrinter(availability, extendedPrinterStatus, name, printerStatus, status, statusInfo));
}
}
I have 6 printers from which 2 are network printers. I've run this with all printers connected and all results looked like this:
Availability = "" // printer["Availability"] = null
ExtendedPrinterStatus = "2" // 2 = Unknown
Name = "{printer name here}"
PrinterStatus = "3" // 3 = Idle
Status = "Unknown"
StatusInfo = "" // Null
So the only difference between the printers is the name.
I ran the script again but this time I disconnected my laptop from the network. So 2 of the printers were not connected anymore in this case.
The strange thing (for me) is, the results were exactly the same.
The reason I ran this test is, to figure out which field I'd need to use for my case.
So at the end, I have not been able to figure out how to figure out if a printer is connected or not.
So what I'd like, is a way to figure out the installed + connected printers in C#. If there is a way to do it without the use of WMI classes, that's also fine by me, as long as it works.
Me and a colleague have tried lots of stuff to find a solution for this and we figured this worked:
private string[] GetAvailablePrinters()
{
var installedPrinters = new string[PrinterSettings.InstalledPrinters.Count];
PrinterSettings.InstalledPrinters.CopyTo(installedPrinters, 0);
var printers = new List<string>();
var printServers = new List<string>();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
foreach (var printer in searcher.Get())
{
var serverName = #"\\" + printer["SystemName"].ToString().TrimStart('\\');
if (!printServers.Contains(serverName))
printServers.Add(serverName);
}
foreach (var printServer in printServers)
{
var server = new PrintServer(printServer);
try
{
var queues = server.GetPrintQueues();
printers.AddRange(queues.Select(q => q.Name));
}
catch (Exception)
{
// Handle exception correctly
}
}
return printers.ToArray();
}
The trick is that when a printserver is not available, GetPrintQueues will throw some specific exception. By only adding the printers that don't throw such an exception, we get a list of all the connected printers. This doesn't check if a printer is turned on/off because that actually doesn't matter. If it is turned off, the document will just be placed in the print queue and it can be printed later on.
I hope this helps others who bump into this problem.
Sidenote:
The reason I decided not to catch that specific exception, is because I would have to reference a dll just for that exception.
Is there a way to check the score in an ASP.Net application? A class or something similar for .Net? How about other Spam Filters out there.
--Edited
I am looking for a way to check the spam score of the email messages in C#.
Here is my super simplified "just check the score" code for connecting to a running Spam Assassin email check from C# which I wrote for http://elasticemail.com. Just setup SA to run on a server and set the access permissions.
Then you can use this code to call it:
public class SimpleSpamAssassin
{
public class RuleResult
{
public double Score = 0;
public string Rule = "";
public string Description = "";
public RuleResult() { }
public RuleResult(string line)
{
Score = double.Parse(line.Substring(0, line.IndexOf(" ")).Trim());
line = line.Substring(line.IndexOf(" ") + 1);
Rule = line.Substring(0, 23).Trim();
Description = line.Substring(23).Trim();
}
}
public static List<RuleResult> GetReport(string serverIP, string message)
{
string command = "REPORT";
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0} SPAMC/1.2\r\n", command);
sb.AppendFormat("Content-Length: {0}\r\n\r\n", message.Length);
sb.AppendFormat(message);
byte[] messageBuffer = Encoding.ASCII.GetBytes(sb.ToString());
using (Socket spamAssassinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
spamAssassinSocket.Connect(serverIP, 783);
spamAssassinSocket.Send(messageBuffer);
spamAssassinSocket.Shutdown(SocketShutdown.Send);
int received;
string receivedMessage = string.Empty;
do
{
byte[] receiveBuffer = new byte[1024];
received = spamAssassinSocket.Receive(receiveBuffer);
receivedMessage += Encoding.ASCII.GetString(receiveBuffer, 0, received);
}
while (received > 0);
spamAssassinSocket.Shutdown(SocketShutdown.Both);
return ParseResponse(receivedMessage);
}
}
private static List<RuleResult> ParseResponse(string receivedMessage)
{
//merge line endings
receivedMessage = receivedMessage.Replace("\r\n", "\n");
receivedMessage = receivedMessage.Replace("\r", "\n");
string[] lines = receivedMessage.Split('\n');
List<RuleResult> results = new List<RuleResult>();
bool inReport = false;
foreach (string line in lines)
{
if (inReport)
{
try
{
results.Add(new RuleResult(line.Trim()));
}
catch
{
//past the end of the report
}
}
if (line.StartsWith("---"))
inReport = true;
}
return results;
}
}
Usage is quite easy:
List<RuleResult> spamCheckResult = SimpleSpamAssassin.GetReport(IP OF SA Server, FULL Email including headers);
It will return the list of spam check rules you hit and the resulting score impact.
I am not exactly sure if that's what you are searching for, but there is a C# wrapper that simplifies the communication with a SpamAssassin server on Code Project:
A C# Wrapper for the SpamAssassin Protocol
Hope that helps!
I was wondering if there is a way to programmatically check how many messages are in a private or public MSMQ using C#? I have code that checks if a queue is empty or not using the peek method wrapped in a try/catch, but I've never seen anything about showing the number of messages in the queue. This would be very helpful for monitoring if a queue is getting backed up.
You can read the Performance Counter value for the queue directly from .NET:
using System.Diagnostics;
// ...
var queueCounter = new PerformanceCounter(
"MSMQ Queue",
"Messages in Queue",
#"machinename\private$\testqueue2");
Console.WriteLine( "Queue contains {0} messages",
queueCounter.NextValue().ToString());
There is no API available, but you can use GetMessageEnumerator2 which is fast enough. Sample:
MessageQueue q = new MessageQueue(...);
int count = q.Count();
Implementation
public static class MsmqEx
{
public static int Count(this MessageQueue queue)
{
int count = 0;
var enumerator = queue.GetMessageEnumerator2();
while (enumerator.MoveNext())
count++;
return count;
}
}
I also tried other options, but each has some downsides
Performance counter may throw exception "Instance '...' does not exist in the specified Category."
Reading all messages and then taking count is really slow, it also removes the messages from queue
There seems to be a problem with Peek method which throws an exception
If you need a fast method (25k calls/second on my box), I recommend Ayende's version based on MQMgmtGetInfo() and PROPID_MGMT_QUEUE_MESSAGE_COUNT:
for C#
https://github.com/hibernating-rhinos/rhino-esb/blob/master/Rhino.ServiceBus/Msmq/MsmqExtensions.cs
for VB
https://gist.github.com/Lercher/5e1af6a2ba193b38be29
The origin was probably http://functionalflow.co.uk/blog/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in/ but I'm not convinced that this implementation from 2008 works any more.
We use the MSMQ Interop. Depending on your needs you can probably simplify this:
public int? CountQueue(MessageQueue queue, bool isPrivate)
{
int? Result = null;
try
{
//MSMQ.MSMQManagement mgmt = new MSMQ.MSMQManagement();
var mgmt = new MSMQ.MSMQManagementClass();
try
{
String host = queue.MachineName;
Object hostObject = (Object)host;
String pathName = (isPrivate) ? queue.FormatName : null;
Object pathNameObject = (Object)pathName;
String formatName = (isPrivate) ? null : queue.Path;
Object formatNameObject = (Object)formatName;
mgmt.Init(ref hostObject, ref formatNameObject, ref pathNameObject);
Result = mgmt.MessageCount;
}
finally
{
mgmt = null;
}
}
catch (Exception exc)
{
if (!exc.Message.Equals("Exception from HRESULT: 0xC00E0004", StringComparison.InvariantCultureIgnoreCase))
{
if (log.IsErrorEnabled) { log.Error("Error in CountQueue(). Queue was [" + queue.MachineName + "\\" + queue.QueueName + "]", exc); }
}
Result = null;
}
return Result;
}
//here queue is msmq queue which you have to find count.
int index = 0;
MSMQManagement msmq = new MSMQManagement() ;
object machine = queue.MachineName;
object path = null;
object formate=queue.FormatName;
msmq.Init(ref machine, ref path,ref formate);
long count = msmq.MessageCount();
This is faster than you selected one.
You get MSMQManagement class refferance inside "C:\Program Files (x86)\Microsoft SDKs\Windows" just brows in this address you will get it. for more details you can visit http://msdn.microsoft.com/en-us/library/ms711378%28VS.85%29.aspx.
I had real trouble getting the accepted answer working because of the xxx does not exist in the specified Category error. None of the solutions above worked for me.
However, simply specifying the machine name as below seems to fix it.
private long GetQueueCount()
{
try
{
var queueCounter = new PerformanceCounter("MSMQ Queue", "Messages in Queue", #"machineName\private$\stream")
{
MachineName = "machineName"
};
return (long)queueCounter.NextValue();
}
catch (Exception e)
{
return 0;
}
}
The fastest method I have found to retrieve a message queue count is to use the peek method from the following site:
protected Message PeekWithoutTimeout(MessageQueue q, Cursor cursor, PeekAction action)
{
Message ret = null;
try
{
ret = q.Peek(new TimeSpan(1), cursor, action);
}
catch (MessageQueueException mqe)
{
if (!mqe.Message.ToLower().Contains("timeout"))
{
throw;
}
}
return ret;
}
protected int GetMessageCount(MessageQueue q)
{
int count = 0;
Cursor cursor = q.CreateCursor();
Message m = PeekWithoutTimeout(q, cursor, PeekAction.Current);
{
count = 1;
while ((m = PeekWithoutTimeout(q, cursor, PeekAction.Next)) != null)
{
count++;
}
}
return count;
}
This worked for me. Using a Enumarator to make sure the queue is empty first.
Dim qMsg As Message ' instance of the message to be picked
Dim privateQ As New MessageQueue(svrName & "\Private$\" & svrQName) 'variable svrnme = server name ; svrQName = Server Queue Name
privateQ.Formatter = New XmlMessageFormatter(New Type() {GetType(String)}) 'Formating the message to be readable the body tyep
Dim t As MessageEnumerator 'declared a enumarater to enable to count the queue
t = privateQ.GetMessageEnumerator2() 'counts the queues
If t.MoveNext() = True Then 'check whether the queue is empty before reading message. otherwise it will wait forever
qMsg = privateQ.Receive
Return qMsg.Body.ToString
End If
If you want a Count of a private queue, you can do this using WMI.
This is the code for this:
// You can change this query to a more specific queue name or to get all queues
private const string WmiQuery = #"SELECT Name,MessagesinQueue FROM Win32_PerfRawdata_MSMQ_MSMQQueue WHERE Name LIKE 'private%myqueue'";
public int GetCount()
{
using (ManagementObjectSearcher wmiSearch = new ManagementObjectSearcher(WmiQuery))
{
ManagementObjectCollection wmiCollection = wmiSearch.Get();
foreach (ManagementBaseObject wmiObject in wmiCollection)
{
foreach (PropertyData wmiProperty in wmiObject.Properties)
{
if (wmiProperty.Name.Equals("MessagesinQueue", StringComparison.InvariantCultureIgnoreCase))
{
return int.Parse(wmiProperty.Value.ToString());
}
}
}
}
}
Thanks to the Microsoft.Windows.Compatibility package this also works in netcore/netstandard.
The message count in the queue can be found using the following code.
MessageQueue messageQueue = new MessageQueue(".\\private$\\TestQueue");
var noOFMessages = messageQueue.GetAllMessages().LongCount();