简体   繁体   English

具有多个客户端的命名管道服务器 (C#)

[英]Named pipe server with multiple clients (C#)

I have a named pipe server written in C#.我有一个用 C# 编写的命名管道服务器。 The gist of the implementation is:实施的要点是:

    void BeginWaitForNextConnection()
    {
        var pipe = new NamedPipeServerStream(
            PipeName,
            PipeDirection.InOut,
            NamedPipeServerStream.MaxAllowedServerInstances,
            PipeTransmissionMode.Byte,
            PipeOptions.Asynchronous,
            0, // default in buffer size
            0, // default out buffer size
            CreateAllAccessPipeSecurity());

        pipe.BeginWaitForConnection(ClientRequestHandler, pipe);
    }

    void ClientRequestHandler(IAsyncResult ar)
    {
        // Clean up the async call state.
        NamedPipeServerStream pipe = (NamedPipeServerStream)ar.AsyncState;

        pipe.EndWaitForConnection(ar);

        // If we've been asked to shut down, go away.
        if (_stopping)
        {
            pipe.Close();
            return;
        }

        // Set up for the next caller.
        BeginWaitForNextConnection();

        // Handle this client's I/O. This code wraps the pipe stream in BinaryReader and BinaryWriter objects and handles communication with the client.
        HandlePipeClient(pipe);
    }

This works perfectly fine -- until multiple instances are trying to connect in quick succession.这工作得很好——直到多个实例试图快速连续连接。 My client code specifies a 10 second timeout, so I would expect that even if 10 instances tried to connect in the same second, they should all succeed, because it shouldn't take 10 seconds for this code to cycle through 10 iterations of ClientRequestHandler callbacks through into BeginWaitForNextConnection -- but this is indeed what I see.我的客户端代码指定了 10 秒超时,所以我希望即使 10 个实例尝试在同一秒内连接,它们都应该成功,因为此代码循环通过 10 次ClientRequestHandler回调迭代不应该花费 10 秒通过BeginWaitForNextConnection —— 但这确实是我所看到的。 For the occasional one-off connection, this code is very reliable, but if I hit it with frequent requests, it appears that perhaps if a request for connection arrives between the callback and the next BeginWaitForConnection , that connection does not queue up and get picked up immediately -- it simply gets lost.对于偶尔的一次性连接,此代码非常可靠,但如果我频繁请求它,似乎如果连接请求在回调和下一个BeginWaitForConnection之间到达,则该连接不会排队并被选中立即起来——它只是迷路了。

Is this expected??这是预期的吗?? What is the idiomatically correct solution?什么是惯用正确的解决方案? Do I just have to spool up a whole bunch of threads all waiting for connections at once?我是否只需要同时处理一大堆等待连接的线程

I had a similar need.我也有类似的需求。

I ended up with a server thread per connection, with each thread created right after the previous client connection.我最终每个连接都有一个服务器线程,每个线程都是在上一个客户端连接之后创建的。

private void ServerConnectToPipe()
{
    var bw = new BackgroundWorker();
    bw.DoWork += (s, e) => DoServerStuff();
    bw.RunWorkerAsync();
}

private void DoServerStuff()
{
    var serverStream = new NamedPipeServerStream("PipeName", PipeDirection.In, NamedPipeServerStream.MaxAllowedServerInstances);
    var streamReader = new StreamReader(serverStream);

    serverStream.WaitForConnection();

    ServerConnectToPipe();

    Log("Server connection", $"Client connected !");
    while (true)
    {
        var line = streamReader.ReadLine();
        // do stuff
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM