当前位置:编程学习 > C#/ASP.NET >>

求一最佳解决方案关于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#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,