VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • c#线程系列讲座(3)线程池和文件下载服务器

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
  如果设计一个服务器程序,每当处理用户请求时,都开始一个线程,将会在一定程序上消耗服务器的资源。为此,一个最好的解决方法就是在服务器启动之前,事先创建一些线程对象,然后,当处理客户端请求时,就从这些建好的线程中获得线程对象,并处理请求。保存这些线程对象的结构就叫做线程池。
  在C#中可以通过System.Threading.ThreadPool类来实现,在默认情况下,ThreadPool最大可建立500个工作线程和1000个I/O线程(根据机器CPU个数和.net framework版本的不同,这些数据可能会有变化)。下面是一个用C#从线程池获得线程的例子:
privatestaticvoidexecute(objectstate)
{
  Console.WriteLine(state);   
}
staticvoidMain(string[]args)
{
 
  intworkerThreads;
  intcompletionPortThreads;
    
  ThreadPool.GetMaxThreads(outworkerThreads,outcompletionPortThreads);
  Console.WriteLine(workerThreads);
  Console.WriteLine(completionPortThreads);  
  ThreadPool.QueueUserWorkItem(execute,"线程1"); //从线程池中得到一个线程,并运行execute
  ThreadPool.QueueUserWorkItem(execute,"线程2");
  ThreadPool.QueueUserWorkItem(execute,"线程3");
  Console.ReadLine();
}
  下图为上面代码的运行结果。

  要注意的是,使用ThreadPool获得的线程都是后台线程。
  下面的程序是我设计的一个下载文件服务器的例子。这个例子从ThreadPool获得线程,并处理相应的客户端请求。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading;
usingSystem.Net.Sockets;
usingSystem.IO;
namespaceMyThread
{
  classFileServer
  {
    privateStringroot;
    privateThreadlistenerThread;
    privatevoidworker(objectstate)
    {
      TcpClientclient=stateasTcpClient;
      try
      {
        client.ReceiveTimeout=2000;
        Streamstream=client.GetStream();
        System.IO.StreamReadersr=newStreamReader(stream);
        Stringline=sr.ReadLine();
        String[]array=line.Split('');
        Stringpath=array[1].Replace('/','');
        Stringfilename=root+path;
        if(File.Exists(filename)) //如果下载文件存在,开始下载这个文件
        {
          FileStreamfileStream=newFileStream(filename,FileMode.Open,FileAccess.Read,
                              FileShare.Read);
          byte[]buffer=newbyte[8192];//每次下载8K
          intcount=0;
          StringresponseHeader="HTTP/1.1200OKrn"+
                      "Content-Type:application/octet-streamrn"+
                      "Content-Disposition:attachment;filename="+
                          filename.Substring(filename.LastIndexOf("")+1)+"rnrn";
          byte[]header=ASCIIEncoding.ASCII.GetBytes(responseHeader);
          stream.Write(header,0,header.Length);
          while((count=fileStream.Read(buffer,0,buffer.Count()))>0)
          {
            stream.Write(buffer,0,count);
          }
          Console.WriteLine(filename+"下载完成");
        }
        else //文件不存在,输出提示信息
        {
          Stringresponse="HTTP/1.1200OKrnContent-Type:text/plain;charset=utf-8rnrn文件不存在";
          byte[]buffer=ASCIIEncoding.UTF8.GetBytes(response);
          stream.Write(buffer,0,buffer.Length);
        }
      }
      catch(Exceptione)
      {
        Console.WriteLine(e.Message);
      }
      finally
      {
        if(client!=null)
        {
          client.Close();
        }
      }
    }
    privatevoidlistener()
    {
      TcpListenerlistener=newTcpListener(1234);
      listener.Start(); //开始监听客户端请求
      TcpClientclient=null;
      while(true)
      {
        client=listener.AcceptTcpClient();
        client.ReceiveTimeout=2000;
        ThreadPool.QueueUserWorkItem(worker,client); //从线程池中获得一个线程来处理客户端请求
      }
    }
    publicFileServer(Stringroot)
    {
      this.root=root;    
    }
    publicvoidstart()
    {
      listenerThread=newThread(listener);
      listenerThread.Start(); //开始运行监听线程
    }
  }
}
  FileServer类的使用方法:
  FileServer fs = new FileServer(“d:download”);
  
fs.start();// 端口为1234
  如果d:"download目录中有一个叫aa.exe的文件,在浏览器中输入如下的地址可下载:
  http://localhost:1234/aa.exe
  下图为下载对话框:

  要注意的是,本程序并没有处理含有中文和其他特殊字符(如空格)的url,因为,文件名要为英文名(不能有空格等特殊字符)。
  文章来源:http://www.cnblogs.com/nokiaguy/archive/2008/07/18/1246299.html
  下面的程序是我设计的一个下载文件服务器的例子。这个例子从ThreadPool获得线程,并处理相应的客户端请求。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading;
usingSystem.Net.Sockets;
usingSystem.IO;
namespaceMyThread
{
  classFileServer
  {
    privateStringroot;
    privateThreadlistenerThread;
    privatevoidworker(objectstate)
    {
      TcpClientclient=stateasTcpClient;
      try
      {
        client.ReceiveTimeout=2000;
        Streamstream=client.GetStream();
        System.IO.StreamReadersr=newStreamReader(stream);
        Stringline=sr.ReadLine();
        String[]array=line.Split('');
        Stringpath=array[1].Replace('/','');
        Stringfilename=root+path;
        if(File.Exists(filename)) //如果下载文件存在,开始下载这个文件
        {
          FileStreamfileStream=newFileStream(filename,FileMode.Open,FileAccess.Read,
                              FileShare.Read);
          byte[]buffer=newbyte[8192];//每次下载8K
          intcount=0;
          StringresponseHeader="HTTP/1.1200OKrn"+
                      "Content-Type:application/octet-streamrn"+
                      "Content-Disposition:attachment;filename="+
                          filename.Substring(filename.LastIndexOf("")+1)+"rnrn";
          byte[]header=ASCIIEncoding.ASCII.GetBytes(responseHeader);
          stream.Write(header,0,header.Length);
          while((count=fileStream.Read(buffer,0,buffer.Count()))>0)
          {
            stream.Write(buffer,0,count);
          }
          Console.WriteLine(filename+"下载完成");
        }
        else //文件不存在,输出提示信息
        {
          Stringresponse="HTTP/1.1200OKrnContent-Type:text/plain;charset=utf-8rnrn文件不存在";
          byte[]buffer=ASCIIEncoding.UTF8.GetBytes(response);
          stream.Write(buffer,0,buffer.Length);
        }
      }
      catch(Exceptione)
      {
        Console.WriteLine(e.Message);
      }
      finally
      {
        if(client!=null)
        {
          client.Close();
        }
      }
    }
    privatevoidlistener()
    {
      TcpListenerlistener=newTcpListener(1234);
      listener.Start(); //开始监听客户端请求
      TcpClientclient=null;
      while(true)
      {
        client=listener.AcceptTcpClient();
        client.ReceiveTimeout=2000;
        ThreadPool.QueueUserWorkItem(worker,client); //从线程池中获得一个线程来处理客户端请求
      }
    }
    publicFileServer(Stringroot)
    {
      this.root=root;    
    }
    publicvoidstart()
    {
      listenerThread=newThread(listener);
      listenerThread.Start(); //开始运行监听线程
    }
  }
}
  FileServer类的使用方法:
  FileServer fs = new FileServer(“d:download”);
  
fs.start();// 端口为1234
  如果d:"download目录中有一个叫aa.exe的文件,在浏览器中输入如下的地址可下载:
  http://localhost:1234/aa.exe
  下图为下载对话框:

  要注意的是,本程序并没有处理含有中文和其他特殊字符(如空格)的url,因为,文件名要为英文名(不能有空格等特殊字符)。
  文章来源:http://www.cnblogs.com/nokiaguy/archive/2008/07/18/1246299.html
 


相关教程