练习命名管道的使用
服务端:
class Program { static int maxNumberOfServerInstances =10; static void Main(string[] args) { Console.WriteLine("我是服务端"); //创建多个实例,10定义的是表示一个机器上使用同一管道名称的实例最多10个。最大允许254个
for (int i = 0; i < maxNumberOfServerInstances; i++) { ThreadStart ts = new ThreadStart(CreatePipe); Thread t = new Thread(ts); t.Start(); } Console.Read(); } static void p() { Console.WriteLine("ok"); } static int count=0; static void CreatePipe() { NamedPipeServerStream svr = new NamedPipeServerStream("TYH", PipeDirection.InOut, maxNumberOfServerInstances); try { Console.WriteLine("等待客户端连接 - {0}", ++count); svr.WaitForConnection(); Console.WriteLine("客户端已经连接"); maxNumberOfServerInstances--; Console.WriteLine("还可以使用{0}次", maxNumberOfServerInstances); byte[] msg = new byte[3]; //客户端发送过来的3个字节,仅测试用。只有这样才可以在服务端模拟客户端
svr.Read(msg, 0, 3); Console.WriteLine(msg[2]); svr.RunAsClient(p); //模拟客户端的用户名,模拟的是运行服务器端的进程的用户名
Console.WriteLine(svr.GetImpersonationUserName()); FileStream fs = new FileStream("Wildlife.wmv", FileMode.Open, FileAccess.Read, FileShare.Read); int bufferSize = 102400; byte[] d = new byte[bufferSize]; int total = 0; int line = Console.CursorTop; int readCount = 0; while ((readCount = fs.Read(d, 0, bufferSize)) > 0) { total += readCount; Console.WriteLine("响应字节数{0}kb", total / 1024f);
//以前不知道怎么处理网络传输前和传输后文件大小不一致的问题,这么我自己练习时发现,读多少写多少是最好的方式
svr.Write(d, 0, readCount);
if (readCount == bufferSize)//不是最后一次循环 { Console.CursorTop = line; } else { Console.WriteLine("Done on Server"); } } fs.Close(); svr.Disconnect();//断开很重要,否则客户端一直等待接收数据 using的作用类似 svr.Close(); svr.Dispose(); //实际这样做存在问题,目前还没有解决。会报两种异常但不是总出现:1、所有范例都在使用中(close或dispose后解决);2、指定路径拒绝访问
CreatePipe();//销毁一个实例,又新建一个实例 maxNumberOfServerInstances++; } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
客户端:
class Program { static string pipeName = "TYH"; static void Main(string[] args) { string serverName = ""; try { serverName = ConfigurationManager.AppSettings["serverName"]; Console.WriteLine("我是客户端"); using (NamedPipeClientStream client = new NamedPipeClientStream(serverName, pipeName)) { Console.WriteLine("正在连接服务端"); //设置连接5秒超时
client.Connect(5000); client.Write(new byte[] { 1, 2, 3 }, 0, 3); Console.WriteLine("服务器实例数目:{0}", client.NumberOfServerInstances); int bufferSize = 10240; byte[] d = new byte[bufferSize]; FileStream fs = new FileStream("Wildlife - " + Guid.NewGuid() + ".wmv", FileMode.Create); int line = Console.CursorTop; long total = 0; int readCount = 0; while ((readCount = client.Read(d, 0, bufferSize)) > 0) { total += readCount; Console.WriteLine("此次获取字节{0}byte", readCount); Console.WriteLine("获取到字节{0}kb", total / 1024f); //读到多少写多少,还有一个好处就是无需关心服务器端和客户端的缓冲的大小。否则两端缓冲一样大也不会有问题。但是测试发现跨机器后每次读取的不一定有缓冲这么大,与网络有关
fs.Write(d, 0, readCount); Console.CursorTop = line; } Console.CursorTop += 2; Console.WriteLine("Done on Client"); Console.CursorTop += 1; fs.Close(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); } }
客户端配置文件只存了服务端机器的IP,供客户端访问。可在局域网内传输文件,以前在局域网中用程序访问文件使用共享的方式,而命名管道更简单。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?