2

私はデバッグと同様にこれを回避しようとしましたが、私はここで緩い終わりを迎えています:(これを使用してクライアント接続をチェックする代わりに何かありますか?このコードはコンソールアプリケーションで正常に動作するので、スレッドを推測していますはブロックされていますが、それは私が見ることができない何か他のものかもしれません?

public partial class Form1 : Form
{
    Socket s;

ソケットの宣言。

private void startButton_Click(object sender, EventArgs e)
    {
        checkTimer.Enabled = true;
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }

ボタンを押すと開始するバックグラウンド スレッド。

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
        BackgroundWorker worker = sender as BackgroundWorker;

        working();
}

スレッドは「作業」メソッドを実行します。

 private void working()
 {
     if (threadFirstRun == true)
     {
            threadFirstRun = false;
     }

        try
        {

            String tempAddr = tbAddr.Text;
            IPAddress ipAd = IPAddress.Parse("147.197.204.172");
            // use local m/c IP address, and 
            // use the same in the client
            String tempPort = tbPort.Text;
            /* Initializes the Listener */
            TcpListener myList = new TcpListener(ipAd, 3000);

            /* Start Listeneting at the specified port */
            myList.Start();
            tcConnection1 = "Console:\n" + "The server is running at port 3000...";
            tcConnection2 = "\n" + "The local End point is  :" + myList.LocalEndpoint;
            tcConnection3 = "\n" + "Waiting for a connection.....";

            while (true)
            {
                s = myList.AcceptSocket();
                if (s != null)
                {
                    if (connectionEstab == false)
                    {
                        tcEstab = "\n" + "Connection accepted from " + s.RemoteEndPoint;
                        connectionEstab = true;
                    }


                    byte[] b = new byte[100];
                    int k = s.Receive(b);
                    //Console.WriteLine("Recieved...");
                    for (int i = 0; i < k; i++)
                    {
                        //Console.Write(Convert.ToChar(b[i]));
                        tcValue = tcValue + Convert.ToString(b[i]);
                        valueArray[ii] = (float)Convert.ToDouble(b[i]);
                    }
                    tcValue = tcValue + "\n";
                    ii++;
                }
                else
                {
                    Thread.Sleep(200);
                }
            }

            ASCIIEncoding asen = new ASCIIEncoding();
            s.Send(asen.GetBytes("The string was recieved by the server."));
            rtbConsole.Text = rtbConsole.Text + "\n" + "Sent Acknowledgement";
            /* clean up */
            s.Close();
            myList.Stop();
        }
        catch (Exception ex)
        {
            tcError = "\n\n" + "Error..... " + ex.StackTrace;
        }
}

作業メソッドはサーバーを起動し、myList.AcceptSocket(); の呼び出し時にブロックしますか?

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
        if ((e.Cancelled == true))
        {
            rtbConsole.Text = rtbConsole.Text + "\n" + "Canceled!";
        }

        else if (!(e.Error == null))
        {
            rtbConsole.Text = rtbConsole.Text + "\n\n" + ("Error: " + e.Error.Message);
        }

        else
        {
            rtbConsole.Text = rtbConsole.Text + "\n" + "Done!";
        }
}

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
        rtbConsole.Text = rtbConsole.Text + "\n" + (e.ProgressPercentage.ToString() + "%");
}

private void stopButton_Click(object sender, EventArgs e)
{
        checkTimer.Enabled = false;
        if (bw.WorkerSupportsCancellation == true)
        {
            bw.CancelAsync();
        }
}

いくつかの完全性のための他の方法。

私の問題を説明するのが苦手なので編集してください:(

Android デバイスからのデータの送信は、1 つのスレッドを実行しているコンソール アプリによって受信されますが、同じデバイス上の同じプログラムから同じ IP とポートにデータを送信しても、この Windows フォーム アプリケーションでは何も起こらないようです。別のスレッドはブロックされたままになり、Android アプリは通信を完了してデータを送信できません。

4

2 に答える 2

1

ブロックすることになっています。MSDNから:

AcceptSocket は、データの送受信に使用できる Socket を返すブロッキング メソッドです。ブロックを回避したい場合は、Pending メソッドを使用して、着信接続キューで接続要求が利用可能かどうかを判断します。

非同期バージョンを使用するように実装全体を変えることができます: AcceptSocketAsync. これはメソッドをブロックしないことに注意してください。新しいメソッドSocketが接続されるまで、呼び出し元に制御が返されます。

private async void bw_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    await WorkingAsync();
}

そして内部WorkingAsync

private Task WorkingAsync
{
    // Do all other stuff,

    Socket socket = await myList.AcceptSocketAsync();

   // Do rest of stuff with the socket
}

ThreadPool サーバーに相当する async/await とは何ですか?をお勧めします。非同期 tcp 接続ハンドラの完全な実装

于 2014-07-10T15:50:26.060 に答える