求一最佳解决方案关于c# socket和多线程
功能需求是:在一台电脑上同时连接网络上的几十台服务器的1300多个端口。用socket去连接,返回无法连接的地址和端口(所有服务器的ip地址和相对应的端口存在数据库的表中),请高手看一下下面的代码,我觉得是这里影响了速度,是不是可以一次读取所有的数据然后缓存,我没用过缓存数据表,不知道缓存了后怎么去顺序读取,请大家赐教。。。工具我已经写出来了,但是速度非常的慢,求优化方案。关键代码:
string sql = "select server_name from Server_list";
DataTable dt = common.database.query_records(sql,connStr);
for(int i=0;i<dt.Rows.Count;i++)
{
string sql2 = "select machine_ip,port from server_details where server_id = '"+dt.Rows[i]["server_name"].ToString()+"'";
DataTable dt2 = common.database.query_records(sql2,connStr);
for(int j=0;j<dt2.Rows.Count;j++)
{
this.textBox1.Text += dt.Rows[i]["server_name"].ToString() + "\r\n";
All(dt2.Rows[j]["machine_ip"].ToString(),dt2.Rows[j]["port"].ToString(),dt.Rows[i]["server_name"].ToString());
}
}
--------------------编程问答-------------------- --------------------编程问答-------------------- 你要用多线程去连接,这样单线程肯定很慢了,连接一个服务端是,特别是TCP
很慢 --------------------编程问答-------------------- 关注 --------------------编程问答-------------------- 几年没来CSDN看帖子了
说一下我的办法吧,大家拍砖
先从数据库拿到地址端口的清单,例如:
192.168.1.4:1234
....
192.168.1.5:2345
将这些数据放入一个QUEUE里面
用线程池TheadPool.Acc....WorkThread
方法去从QUEUE里面取地址端口信息进行扫描
扫描结果当然也可以使用QUEUE进行进站处理
例如
private static Queue<string> sQueue = new Queue<string>();
private static void Scan()
{
foreach(datarow row in dt.rows)
{
sQueue.Enqueue(string.format("{0}:{1}",row["IP"],row["port"]);
}
int threadCount = 10;
for(int i=0;i<threadCount;i++)
{
ThreadPool.QueueWork...(new ...Callback(ThreadScan),null);
}
}
private static Queue<string> resultQueue = new Queue<string>();
private static void ThreadScan(object state)
{
string msg = string.em;
lock(sQueue)
{
if(sQueue.Count == 0)
{
return;
}
msg = sQueue.DeQueue();
}
string[]para = ms.split(':');
IPEndPoint rep = new IPEndPoint(Ipaddress.Parse(para[0]),int.Parse(para[1]);
using(Socket sck = new Socket(....))
{
try
{
sck.Connect(rep);
//do something..
lock(resultQueue)
{
resultQueue.EnQueue(msg);//add remote endpoint to the queue
}
sck.Close();
}
} --------------------编程问答-------------------- 当然那个10次循环的位置,也可以自己去创建线程
Thead thread = new Thread(new ThreadStart(ThreadScan));
这样的话,ThreadScan 方法去掉参数就好
个人觉得用TheadPool更方便,效率可能更高,因为线程池会自动维护线程的开启与销毁 --------------------编程问答-------------------- private static void ThreadScan(object state)
{
string msg = string.em;
lock(sQueue)
{
if(sQueue.Count == 0)
{
return;
}
msg = sQueue.DeQueue();
}
string[]para = ms.split(':');
IPEndPoint rep = new IPEndPoint(Ipaddress.Parse(para[0]),int.Parse(para[1]);
using(Socket sck = new Socket(....))
{
try
{
sck.Connect(rep);
//do something..
lock(resultQueue)
{
resultQueue.EnQueue(msg);//add remote endpoint to the queue
}
sck.Close();
}
}
更正如下
private static void ThreadScan(object state)
{
while(true)
{
string msg = string.em;
lock(sQueue)
{
if(sQueue.Count == 0)
{
return;
}
msg = sQueue.DeQueue();
}
string[]para = ms.split(':');
IPEndPoint rep = new IPEndPoint(Ipaddress.Parse(para[0]),int.Parse(para[1]);
using(Socket sck = new Socket(....))
{
try
{
sck.Connect(rep);
//do something..
lock(resultQueue)
{
resultQueue.EnQueue(msg);//add remote endpoint to the queue
}
sck.Close();
}
}
}
补充:.NET技术 , C#