【发布时间】:2020-05-11 20:27:07
【问题描述】:
所以这是来自> [Using Parallel Processing in C# to test a site's ability to withstand a DDOS
的继续我使用这篇 MS KB 文章作为我的示例的基础,除了我不想通过单击按钮运行它,而是通过控制台脚本启动它,然后触发“攻击”方法,该方法循环通过 X 没有相同的 URL,并在返回时返回。这个example from MS 只是向 Microsoft URLS 发出 3 个请求。
为了使它更像知识库文章,我刚刚将按钮单击替换为在控制台应用程序运行时调用的主程序,该程序又调用 Attack(),这是唯一的(目前只是试图获得3 个网址)。在真正的代码中,我有一个循环,但我需要先让这部分工作,这样我才能理解我做错了什么。
但是,当我在命令提示符下运行它时,我得到的只是......
C:\Users\XXX>"C:\Users\XXX\Documents\Visual Studio 2017\Projects\DOSBot\DOSBot
\bin\Release\DOSBot.exe" "https://www.google.com" 1000
10/05/2020 00:00:00: starting script
然后它就结束了,没有像我期望的那样从 HTTP 请求返回消息。
控制台脚本代码如下:
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.ComponentModel.DataAnnotations;
namespace AsyncExample_MultipleTasks
{
class Program
{
// Replaced the MS KB article example of hitting a button with just a Main constructor that runs from the console. I am passing arguments in at the moment URL and no of Requests to make but not currently using them as I want to understand why the MS KB example of making 3 requests is not working
public static void Main(string[] args)
{
if (args.Length > 0)
{
string url = args[0];
int no = Convert.ToInt32(args[1]);
ShowDebug("starting script");
// Attack DOS = new Attack(url,no);
Attack DOS = new Attack();
// Moved from the Attack() constructor but made no difference
DOS.StartAttack();
// The job just seems to end with no error message and DOS.StartAttack() seems to be skipped over
}
}
public static void ShowDebug(string msg)
{
string debugmsg = DateTime.Now.Date.ToString() + ": " + msg;
Console.WriteLine(debugmsg);
}
}
public class Attack
{
private int Counter = 0; // will hold no of actual HTTP requests completed
private string URL; // URL to hit
private int ReqNo; // No of HTTP request to make
public Attack()//string url, int reqNo=100)
{
this.URL = "http://www.google.com";// url;
this.ReqNo = 100; //reqNo;
//Tried calling this from here but now from the Main Program Constructor but makes no difference
//this.StartAttack();
}
// Tried calling this from the constructor above (commented out), and now from the main Program but neither do anything different
public async void StartAttack()
{
await CreateMultipleTasksAsync();
}
// This would be replaced by my loop with one URL to request and X no of times to request it.
private async Task CreateMultipleTasksAsync()
{
// Declare an HttpClient object, and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };
// Create and start the tasks. As each task finishes, DisplayResults
// displays its length.
Task<int> download1 =
ProcessURLAsync("https://msdn.microsoft.com", client);
Task<int> download2 =
ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client);
Task<int> download3 =
ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
// Await each task.
int length1 = await download1;
int length2 = await download2;
int length3 = await download3;
int total = length1 + length2 + length3;
// Display the total count for the downloaded websites.
Program.ShowDebug("\r\n\r\nTotal bytes returned: {total}\r\n");
}
async Task<int> ProcessURLAsync(string url, HttpClient client)
{
var byteArray = await client.GetByteArrayAsync(url);
DisplayResults(url, byteArray);
return byteArray.Length;
}
// Why is this not firing on return of the HTTP request?
private void DisplayResults(string url, byte[] content)
{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "https://".
var displayURL = url.Replace("https://", "");
Program.ShowDebug($"\n{displayURL,-58} {bytes,8}");
}
}
}
所以 DisplayResults 方法根本没有被调用,理论上从我读过的内容来看,当 HTTP 响应返回字节数等时应该触发它。但是我根本看不到它正在运行。
我是否缺少参考资料或其他内容?我在 Visual Studio 2017 的 64 位 Windows 笔记本电脑上使用 .NET 4.6.1。
【问题讨论】:
-
提示:如果您不等待
StartAttack,那么您的程序执行将移至Main方法的下一行,然后是下一行,然后您的程序结束。另请注意,从 C# 版本开始......呃,7.1?异步主要方法是可能的。 -
这里的问题是你的程序在调用
DOS.StartAttack之后就存在了。因为, main 不会等待方法执行完成,这就是为什么您看不到DisplayResults被调用的原因。将public async void StartAttack()更改为public async Task StartAttack()并以DOS.StartAttack().GetResult().GetAwaiter();调用。或者,您可以使用 async main 方法。 -
请注意是否应该在 SO 上发布此类内容?
-
当我在构造函数中更改 public Attack(), this.StartAttack() 到 this.StartAttack().GetResult().GetAwaiter(); - 我收到 GetResult() 不是方法(不在我的课程中)的错误。 - 如果我在程序中更改最初运行的 Main 方法并创建类(希望)在并行 HTTP 请求中循环到 public async Main(string[] args) - 我得到“找不到类型或命名空间异步“ - 另外,如果我将 Main 更改为 public async void Main(string[] args) 我得到“程序不包含入口点的静态 Main 方法” - 请提供更多示例代码
标签: c# http parallel-processing async-await ddos