日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#线程系列讲座(3):线程池和文件下载服务器

發布時間:2025/7/14 C# 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#线程系列讲座(3):线程池和文件下载服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
如果設計一個服務器程序,每當處理用戶請求時,都開始一個線程,將會在一定程序上消耗服務器的資源。為此,一個最好的解決方法就是在服務器啟動之前,事先創建一些線程對象,然后,當處理客戶端請求時,就從這些建好的線程中獲得線程對象,并處理請求。保存這些線程對象的結構就叫做線程池。 C#中可以通過System.Threading.ThreadPool類來實現,在默認情況下,ThreadPool最大可建立500個工作線程和1000I/O線程(根據機器CPU個數和.net framework版本的不同,這些數據可能會有變化)。下面是一個用C#從線程池獲得線程的例子:
private?static?void?execute(object?state)
{
????Console.WriteLine(state);??????
}
static?void?Main(string[]?args)
{
??
????
int?workerThreads;
????
int?completionPortThreads;
?????????
????ThreadPool.GetMaxThreads(
out?workerThreads,?out?completionPortThreads);
????Console.WriteLine(workerThreads);
????Console.WriteLine(completionPortThreads);????
????ThreadPool.QueueUserWorkItem(execute,
"線程1");???//?從線程池中得到一個線程,并運行execute
????ThreadPool.QueueUserWorkItem(execute,?"線程2");
????ThreadPool.QueueUserWorkItem(execute,?
"線程3");
????Console.ReadLine();
}
下圖為上面代碼的運行結果。 ? 要注意的是,使用ThreadPool獲得的線程都是后臺線程。 下面的程序是我設計的一個下載文件服務器的例子。這個例子從ThreadPool獲得線程,并處理相應的客戶端請求。
? using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?System.Threading;
using?System.Net.Sockets;
using?System.IO;

namespace?MyThread
{
????
class?FileServer
????{
????????
private?String?root;
????????
private?Thread?listenerThread;

????????
private?void?worker(object?state)
????????{
?????????????TcpClient?client?
=?state?as?TcpClient;
?????????????
try
?????????????{

?????????????????client.ReceiveTimeout?
=?2000;
?????????????????Stream?stream?
=?client.GetStream();
?????????????????System.IO.StreamReader?sr?
=?new?StreamReader(stream);
?????????????????String?line?
=?sr.ReadLine();
?????????????????String[]?array?
=?line.Split('?');
?????????????????String?path?
=?array[1].Replace('/',?'\\');
?????????????????String?filename?
=?root?+?path;
?????????????????
if?(File.Exists(filename))??//?如果下載文件存在,開始下載這個文件
?????????????????{
?????????????????????FileStream?fileStream?
=?new?FileStream(filename,?FileMode.Open,?FileAccess.Read,?
?????????????????????????????????????????????????????????? FileShare.Read);
?????????????????????
byte[]?buffer?=?new?byte[8192];?//?每次下載8K
?????????????????????int?count?=?0;
?????????????????????String?responseHeader?
=?"HTTP/1.1?200?OK\r\n"?+
?????????????????????????????????????????????
"Content-Type:application/octet-stream\r\n"?+
?????????????????????????????????????????????
"Content-Disposition:attachment;filename="?+
?????????????????????????????????????????????????? filename.Substring(filename.LastIndexOf("\\")?+?1)?+?"\r\n\r\n";
?????????????????????
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??//?文件不存在,輸出提示信息
?????????????????{
?????????????????????String?response?
=?"HTTP/1.1?200?OK\r\nContent-Type:text/plain;charset=utf-8\r\n\r\n文件不存在";
?????????????????????
byte[]?buffer?=?ASCIIEncoding.UTF8.GetBytes(response);
?????????????????????stream.Write(buffer,?
0,?buffer.Length);
?????????????????}

?????????????}
?????????????
catch?(Exception?e)
?????????????{
?????????????????Console.WriteLine(e.Message);
?????????????}
?????????????
finally
?????????????{
?????????????????
if?(client?!=?null)
?????????????????{
?????????????????????client.Close();
?????????????????}
?????????????}
????????}

????????
private?void?listener()
????????{
????????????TcpListener?listener?
=?new?TcpListener(1234);
????????????listener.Start();??
//?開始監聽客戶端請求
????????????TcpClient?client?=?null;

????????????
while?(true)
????????????{
????????????????client?
=?listener.AcceptTcpClient();
????????????????client.ReceiveTimeout?
=2000;
????????????????ThreadPool.QueueUserWorkItem(worker,?client);??
//?從線程池中獲得一個線程來處理客戶端請求
????????????}
????????}
????????
public?FileServer(String?root)
????????{
????????????
this.root=?root;?????????
????????}
????????
public?void?start()
????????{
????????????listenerThread?
=?new?Thread(listener);
????????????listenerThread.Start();??
//?開始運行監聽線程
????????}
????}
}

FileServer類的使用方法:

??? FileServer fs = new FileServer(“d:\\download”); fs.start();?//?端口為1234 如果d:"download目錄中有一個叫aa.exe的文件,在瀏覽器中輸入如下的地址可下載:
??? http://localhost:1234/aa.exe 下圖為下載對話框:
要注意的是,本程序并沒有處理含有中文和其他特殊字符(如空格)的url,因為,文件名要為英文名(不能有空格等特殊字符)。






本文轉自 androidguy 51CTO博客,原文鏈接:http://blog.51cto.com/androidguy/216664,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的C#线程系列讲座(3):线程池和文件下载服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。