命名管道重复使用问题。

cnwolfs 2013-06-24 05:25:43
例如服务端有100个命名管道线程,每个命名管道均可被客户端使用一次连接,也就是连接中断后,服务端的这个管道也就不能用了。
那我的服务端不能被用过100个连接后就不响应了啊。
请问该如何处理?

服务端代码:


for (int i = 0; i < 100; i++)
{
System.IO.Pipes.NamedPipeServerStream mPipeServer = new System.IO.Pipes.NamedPipeServerStream("HE.OKCard", System.IO.Pipes.PipeDirection.InOut, 100, System.IO.Pipes.PipeTransmissionMode.Message, System.IO.Pipes.PipeOptions.Asynchronous);
//mPipeServer.WriteTimeout = 1000;
System.Threading.ThreadPool.QueueUserWorkItem(delegate
{
mPipeServer.BeginWaitForConnection((o) =>
{
System.IO.Pipes.NamedPipeServerStream mServer = (System.IO.Pipes.NamedPipeServerStream)o.AsyncState;
mServer.EndWaitForConnection(o);
System.IO.StreamReader mSR = new System.IO.StreamReader(mServer);
System.IO.StreamWriter mSW = new System.IO.StreamWriter(mServer);
string mResult = null;
StringBuilder mSB = new StringBuilder();
string mClientName = mServer.GetHashCode() + " " + mServer.GetImpersonationUserName();

while (true)
{
mResult = mSR.ReadLine();
if (mResult == null || mResult == "bye")
{
break;
}
else
{
mSB.AppendLine(mClientName + " : " + mResult);
RefreshTextBox(this.txtServer, mSB.ToString());
mSW.Write("Reply:" + mResult);
}
}
}, mPipeServer);
});
}



客户端代码:

private System.IO.Pipes.NamedPipeClientStream mPipeClient1 = null;


if (mPipeClient1 == null)
{
mPipeClient1 = new System.IO.Pipes.NamedPipeClientStream("127.0.0.1", "HE.OKCard", System.IO.Pipes.PipeDirection.InOut, System.IO.Pipes.PipeOptions.Asynchronous, System.Security.Principal.TokenImpersonationLevel.None);

mPipeClient1.Connect();
}
mSW1 = new System.IO.StreamWriter(mPipeClient1);
mSR1 = new System.IO.StreamReader(mPipeClient1);
mSW1.AutoFlush = true;

mSW1.WriteLine(this.txtClient1.Text);


...全文
397 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xfyxq 2013-06-25
  • 打赏
  • 举报
回复
你可以删除 "System.Threading.ThreadPool.QueueUserWorkItem(delegate {... ...});" 这个线程池的处理,把里面的代码提取出来,因为在里面的代码中等待客户端连接本身就是异步处理了。 我刚看了你客户端的代码,还有一个问题就是你重复定义100个管道名称相同的管道对象,因为你的客户端连接的是指定名称的管道,其它99个管道对象可能会处于闲置状态,也就是说可能始终只有一个管道在工作,这个问题我也不能确定,你可以试试多个客户端同时连接服务器时看有没有客户端处于连接等待状态或是连接失败,如果出现连接等待或是连接失败则说明你还需要修改你的服务器代码。
cnwolfs 2013-06-25
  • 打赏
  • 举报
回复
引用 12 楼 xfyxq 的回复:
一般情况下是每个客户端都需要一个线程为之处理,但目前你服务器代码端的情况来看,你是N*2个线程为之处理(N=客户端个数),在这里有损服务性能。
该如何做比较好?
xfyxq 2013-06-25
  • 打赏
  • 举报
回复
一般情况下是每个客户端都需要一个线程为之处理,但目前你服务器代码端的情况来看,你是N*2个线程为之处理(N=客户端个数),在这里有损服务性能。
cnwolfs 2013-06-25
  • 打赏
  • 举报
回复
没报错,只是无法按预定执行,看样子是少了个初始化啥的,改成下面代码就可以了,就是添加了一条语句。 AsyncCallback aa = null; mPipeServer.BeginWaitForConnection(aa, mPipeServer);//等待连接 aa = (o) => { 补充问下,服务端能够同时为若干客户端连接,例如1000个客户端连接,是不是要初始化1000个线程?
xfyxq 2013-06-25
  • 打赏
  • 举报
回复
我给你提供的代码中,aa采用的是lambda表达式定义,如果是这里编译报错的话,你可以改为委托定义: aa = delegate(IAsyncResult o) { ... ... //代码 } 如果是运行报错,你需要提供详细错误。
xfyxq 2013-06-25
  • 打赏
  • 举报
回复
是编译报错还是运行报错,报什么错?
cnwolfs 2013-06-25
  • 打赏
  • 举报
回复
引用 7 楼 xfyxq 的回复:
还有就是你服务器端代码还可以优化,你启动一个线程池异步进行等待连接处理,然后又再次调用异步等待连接,在这里可以进行优化,其中一个异步操作可以取消。
你给的这段代码没办法运行啊,问题应该是在这部分代码,没调用BeginWaitForConnection AsyncCallback aa = null; aa=(o) => { System.IO.Pipes.NamedPipeServerStream mServer = (System.IO.Pipes.NamedPipeServerStream)o.AsyncState; mServer.EndWaitForConnection(o); 麻烦再帮我修改修改,遇到这样的异步写法,我都搞不清楚了。
xfyxq 2013-06-25
  • 打赏
  • 举报
回复
还有就是你服务器端代码还可以优化,你启动一个线程池异步进行等待连接处理,然后又再次调用异步等待连接,在这里可以进行优化,其中一个异步操作可以取消。
xfyxq 2013-06-25
  • 打赏
  • 举报
回复
你服务器端2个问题:1、缺少调用断开方法;2、缺少再次异步等待连接。 我给你的代码稍做了一下改动,如下:
        System.IO.Pipes.NamedPipeServerStream mPipeServer = new System.IO.Pipes.NamedPipeServerStream("HE.OKCard", System.IO.Pipes.PipeDirection.InOut, 100, System.IO.Pipes.PipeTransmissionMode.Message, System.IO.Pipes.PipeOptions.Asynchronous);
        private void button10_Click(object sender, EventArgs e)
        {
            //mPipeServer.WriteTimeout = 1000;
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                AsyncCallback aa = null;
                aa=(o) =>
                {
                    System.IO.Pipes.NamedPipeServerStream mServer = (System.IO.Pipes.NamedPipeServerStream)o.AsyncState;
                    mServer.EndWaitForConnection(o);
                    System.IO.StreamReader mSR = new System.IO.StreamReader(mServer);
                    System.IO.StreamWriter mSW = new System.IO.StreamWriter(mServer);
                    string mResult = null;
                    StringBuilder mSB = new StringBuilder();
                    string mClientName = String.Format("{0}  {1}", mServer.GetHashCode(), mServer.GetImpersonationUserName());
                    while (true)
                    {
                        mResult = mSR.ReadLine();
                        if (mResult == null || mResult == "bye")
                        {
                            break;
                        }
                        else
                        {
                            mSB.AppendLine(String.Format("{0} : {1}", mClientName, mResult));
                            mSW.Write("Reply:" + mResult);
                            System.Diagnostics.Debug.WriteLine(mResult);
                        }
                    }
                    mPipeServer.Disconnect();//服务器断开,很重要!
                    mPipeServer.BeginWaitForConnection(aa, mPipeServer);//再次等待连接,更重要!!
                };
                mPipeServer.BeginWaitForConnection(aa, mPipeServer);
            });

        }
cnwolfs 2013-06-25
  • 打赏
  • 举报
回复
寻求各位大侠帮助
cnwolfs 2013-06-24
  • 打赏
  • 举报
回复
close了之后就不能在connect了
  • 打赏
  • 举报
回复
mPipeClient1.Connect(); 调用与它对应的Close()方法
cnwolfs 2013-06-24
  • 打赏
  • 举报
回复
引用 1 楼 Return_false 的回复:
可以关闭旧管道,建立新管道,需要随时监测管道的使用情况吧 指定了管道最大数量限制那么在打开的管道达到最大限制后如果不关闭旧管道就无法打开新管道。 对于客户方则无法关闭连接,而只能直接调用CloseHandle关闭管道。
我就是想要寻求关闭旧管道,打开新管道的机制
  • 打赏
  • 举报
回复
可以关闭旧管道,建立新管道,需要随时监测管道的使用情况吧 指定了管道最大数量限制那么在打开的管道达到最大限制后如果不关闭旧管道就无法打开新管道。 对于客户方则无法关闭连接,而只能直接调用CloseHandle关闭管道。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧