我正在构建扫描IP地址的程序。我构建了一个检查
端口的类给定的IP地址。我在循环中将此类作为线程运行。我显然阻止了
的数量可以并行运行的线程。问题是线程总是返回一个退出
代码:259,大约半分钟后,程序挂起。
我尝试在谷歌,论坛中搜索,这里代码259的含义。所以我发现了一些
论坛,它只返回不含任何意义的代码。在其他论坛中,我看到的是
表示使用大量内存时出现问题。所以我尝试在
中只使用2个线程相同常。它仍然无法正常工作。我试图看到另一种使用线程的方法,所以我读了
关于线程池,我更改代码以使用线程池,但它仍然无法正常工作。我是
当然确保在课堂上我不使用全局变量。
代码:
private void Get_Port_With_Status_Thread_Inventer()
{
for (int Thread_Cnt_Get_Port_N_Status = 1; Thread_Cnt_Get_Port_N_Status < IP_Address.Length + 1; Thread_Cnt_Get_Port_N_Status++)
{
if (Open_Threads_Port_N_Status_Counter >= Max_Thread_Allowed)
{
Thread_Cnt_Get_Port_N_Status--;
continue;
}
Thread New_Port_N_Status_Thread = new Thread(new ParameterizedThreadStart(Get_Port_With_Status_Thread));
New_Port_N_Status_Thread.Start(Thread_Cnt_Get_Port_N_Status);
Open_Threads_Port_N_Status_Counter++;
}
End_Get_Port_N_Status_Inventer = true;
}
private void Get_Port_With_Status_Thread(object Index_On_Array_Obj)
{
int Index_On_Array = (int)Index_On_Array_Obj;
string IP_Address_Str = IP_Address[Index_On_Array - 1];
IPEndPoint IP_Address_Connect_Data_Base = new IPEndPoint(IPAddress.Parse(IP_Address_Str), 80);
Socket Socket_IP_Address_Connect_Data_Base = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string Ports_Rep_Index = 80.ToString();
DateTime Current_New_Now_Seconds = DateTime.Now.Date;
try
{
Socket_IP_Address_Connect_Data_Base.Connect(IP_Address_Connect_Data_Base);
Socket_IP_Address_Connect_Data_Base.Disconnect(true);
IP_Port[Index_On_Array - 1] = "Port 80 - Live";
}
catch (SocketException g)
{
IP_Port[Index_On_Array - 1] = "Port 80 - Dead";
}
Open_Threads_Port_N_Status_Counter--;
}
答案 0 :(得分:0)
Get_Port_With_Status_Thread_Inventer中的for循环实际上阻止了当前调用它的线程,直到你完成处理ip地址为止。无论何时需要在C#中使用多线程,都应该使用tasks代替。
对于您的问题,您最好使用parallel foreach loop:
class Status
{
public IPAddress IpAddress { get; set; }
public bool? IsAlive { get; set; }
}
private Status[] ipAddresses = new Status[]
{
new Status()
{
IpAddress = IPAddress.Parse("192.168.1.1")
},
new Status()
{
IpAddress = IPAddress.Parse("192.168.1.2")
},
new Status()
{
IpAddress = IPAddress.Parse("192.168.1.3")
},
};
private void scanPorts()
{
Parallel.ForEach(ipAddresses, scanPort);
}
private void scanPort(Status status)
{
IPEndPoint ipEndPoint = new IPEndPoint(status.IpAddress, 80);
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
try
{
socket.Connect(ipEndPoint);
socket.Disconnect(true);
status.IsAlive = true;
}
catch (SocketException)
{
status.IsAlive = false;
}
}
Parallel.ForEach方法采用IEnumerable(如数组或列表),并为其自己的线程中的数组中的每个元素调用一个方法。 .NET库可以为您创建,运行和销毁线程。您唯一需要担心的是如何正确地在线程之间共享数据。
我制作的Status类有助于保持IPAddress与程序是否可以连接到端口80同步。 IsAlive的默认值为null。您无需担心将索引从一个线程传递到下一个线程。
答案 1 :(得分:-1)
解决方案很简单。不要使用调试器运行多个线程,所以如果你有Microsoft
Visual Studio,你想要运行很多线程,在没有调试器的情况下运行程序!