1

WPF サーバーとクライアント アプリケーションがあります。サーバーを起動すると、受信メッセージのリッスンが開始されます。ただし、アプリケーションに触れたり閉じたりすることはできず、リスニングで「立ち往生」しています。メッセージの処理などの問題で、それがすべきことを行うことを追加する必要があります。しかし、フォームとやり取りすることはできません。非同期サーバーソケットに関連していますか? 何を探すべきかわかりません...

ここに私のサーバーコードがあります:

    private void startServer()
    {
        sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        sck.Bind(new IPEndPoint(0, serverPort));
        sck.Listen(100);

        while (true)
        {
            Socket accepted = sck.Accept();

            Buffer = new byte[accepted.SendBufferSize];
            int bytesRead = accepted.Receive(Buffer);

            byte[] formatted = new byte[bytesRead];

            for (int i = 0; i < bytesRead; i++)
            {
                formatted[i] = Buffer[i];
            }
            string command = Encoding.ASCII.GetString(formatted);
            string[] splittedCommand = command.Split(' ');

            jobsHistory.Items.Add(Encoding.ASCII.GetString(formatted));
            jobsHistory.Refresh();

            Process processToRun = new Process();
            processToRun.StartInfo.FileName = splittedCommand[0];
            processToRun.StartInfo.WorkingDirectory = Path.GetDirectoryName(splittedCommand[0]);
            processToRun.StartInfo.Arguments = "";
            for (int i = 1; i < splittedCommand.Length; i++)
            {
                processToRun.StartInfo.Arguments += " " + splittedCommand[i];
            }

            processToRun.Start();
            accepted.Close();
        }
    }
4

3 に答える 3

1

これが UI スレッドで機能する場合は、ループに結び付けています。UI イベントを処理する機会はありません。それに加えてSocket.Receive、ブロッキングコールがあります。

このサイトと Google の両方に、BackgroundWorker` クラスに関する多数の記事があります。それらを調べることをお勧めします。

于 2013-01-30T08:09:25.317 に答える
1

このように、別のスレッドでリスニングを実行するだけです-

    private void startServer()
    {
        sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        sck.Bind(new IPEndPoint(0, 8080));

        new Thread(() => StartListening(sck)).Start();
    }

    void StartListening(Socket socket)
    {
        socket.Listen(100);

        Accept(socket);
    }

    void Accept(Socket socket)
    {
        while (true)
        {
            Socket accepted = socket.Accept();

            Buffer = new byte[accepted.SendBufferSize];
            int bytesRead = accepted.Receive(Buffer);

            byte[] formatted = new byte[bytesRead];

            for (int i = 0; i < bytesRead; i++)
            {
                formatted[i] = Buffer[i];
            }
            string command = Encoding.ASCII.GetString(formatted);
            string[] splittedCommand = command.Split(' ');

            jobsHistory.Items.Add(Encoding.ASCII.GetString(formatted));
            jobsHistory.Refresh();

            Process processToRun = new Process();
            processToRun.StartInfo.FileName = splittedCommand[0];
            processToRun.StartInfo.WorkingDirectory = Path.GetDirectoryName(splittedCommand[0]);
            processToRun.StartInfo.Arguments = "";
            for (int i = 1; i < splittedCommand.Length; i++)
            {
                processToRun.StartInfo.Arguments += " " + splittedCommand[i];
            }

            processToRun.Start();
            accepted.Close();
        }

        // If you want to start listening again
        socket.Close();
        startServer();
    }
于 2013-01-30T08:09:51.987 に答える
1

BeginAcceptUI スレッドをブロックすることなく、バックグラウンドで接続を受け入れるために使用する必要があります。クライアントが受け入れられると、BeginAccept再度呼び出します。これにより、「ループ」が作成されます。whileその後、ループを削除できます。

メソッドは次のstartServerようになります。

private void startServer()
{
    sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    sck.Bind(new IPEndPoint(0, serverPort));
    sck.Listen(100);

    sck.BeginAccept(Accepted, sck);
}

次に、Acceptedメソッドで次のようにします。

private void Accepted(IAsyncResult result)
{
    Socket sck = result.AsyncState as Socket;
    Socket client = sck.EndAccept(result);

    sck.BeginAccept(Accepted, sck);
}


        Socket accepted = sck.Accept();
于 2013-01-30T08:20:43.490 に答える