0

TcpClient基本的に必要なのはp2p接続です。現在、 sを介して互いに通信している非同期サーバーとクライアントがあります。問題は、サーバーが着信メッセージをほとんど検出せず、通常は最初のメッセージしか受信しないことです。私のサーバーコードはここにあります:

    public void RecieveAsync()
    {

        if (netStream == null) netStream = Server.GetStream();

        netStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, recieveCallBack, netStream);
    }


    public void recieveCallBack(IAsyncResult ar)
    {
        //try
        //{
        int rec = netStream.EndRead(ar);
        if (rec == 0)
        {
            if (Disconnected != null)
            {
                Disconnected(this);
                return;
            }
        }
        else
        {
            if (DataRecieved != null)
            {
                string RecievedData = Encoding.ASCII.GetString(ReadBuffer, 0, rec);
                DataRecieved(RecievedData);
            }

            ReadBuffer = new byte[1024];

        }

    }

Thread.Sleep(1)データを送信するクライアント コードはここにあります (プレーヤーの位置を更新するために、データを で何度も送信する while ループにラップされます)

    public void Send(byte[] data, int index, int length)
    {
        //add data as state

        //socket.NoDelay = true;

        Buffer.BlockCopy(data, 0, writeBuffer, index, length);

        if (netStream == null) netStream = TcpClient.GetStream();

        netStream.BeginWrite(writeBuffer, 0, writeBuffer.Length, sendCallback, netStream);



    }

    private void sendCallback(IAsyncResult ar)
    {
        //try
        //{
           netStream.EndWrite(ar);

            //if (ar.AsyncState != null)
            //{
            //    byte[] buffer = (byte[])ar.AsyncState;
            //    socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, sendCallback, null);
            //    return;
            //}

            if (OnSend != null)
            {
                OnSend(this);
            }

        //catch (Exception ex)
        //{
        //    System.Windows.Forms.MessageBox.Show(ex.ToString());
        //    return;
        //}
    }

デフォルトのバッファ サイズは 1024 で、が true のRecieveAsync場合にのみ呼び出さnetStream.DataAvailibleれ、サーバー ループで常にチェックされます。

編集 ::

これはサーバーを呼び出すコードです

            while (true)
            {

                byte[] playerData = NormalText(PreparePlayerData());

                server.Send(playerData, 0, playerData.Length);

                if (server.Server.Connected)
                {

                    server.netStream = server.Server.GetStream();

                    while (server.netStream.DataAvailable)
                    {
                        server.RecieveAsync();
                        server.netStream = server.Server.GetStream();
                    }

                }


                Thread.Sleep(1);

            }
4

1 に答える 1

1

ネットワークプログラミングに関しては、さまざまな方法の背後で何が起こっているのかを知るのに役立ちます。receiveメソッドの場合、を使用してコールバックを正しく構成します

netStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, recieveCallBack, netStream);

これにより、データが受信されたときにrecieveCallBack()がトリガーされますが、次の行が興味深いものになり始めます。また、netStream.BeginReadを1回呼び出すだけで、コールバックが1回だけトリガーされることにも注意してください。データのリッスンを継続する場合は、netStream.BeginReadを再度呼び出す必要があります。

string RecievedData = Encoding.ASCII.GetString(ReadBuffer, 0, rec);

フレームワークは、送信で書き込んだすべてのデータを受信することを保証するものではありません。いくつかのデータを受け取ったら、それを文字列に変換する前に、すべてが揃っていることを確認する必要があります。すべてを受け取っていない場合は、別の電話をかける必要があります

netStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, recieveCallBack, netStream);

そして、さらに待ちます。

これはプログラミングのトリッキーな側面ですが、あなたは明らかに順調に進んでいます。作業例から逆方向に作業するのに役立つ場合は、オープンソースネットワークライブラリnetworkcomms.netからのメソッドIncomingTCPPacketHandler()(recieveCallBackメソッドと同等)をここでチェックアウトします

于 2013-01-23T15:35:25.653 に答える