3

以下のコードに問題があります。UDPブロードキャストを使用して現在の日付/時刻を送信し、このメッセージをリッスンします。このコードの現在の使用はローカルです。同じコンピューターの同じアプリケーションで送信と受信を使用します。私はまだ2台のコンピューター間でそれを試していません。

public class Agent
{
    public static int Port = 33333;
    public delegate void OnMessageHandler(string message);

    Socket socketSend;
    Socket socketReceive;

    bool receiving = false;
    Thread receiveThread;

    public event OnMessageHandler OnMessage;

    public Agent()
    {
        socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socketSend.EnableBroadcast = true;

        socketSend.Connect(new IPEndPoint(IPAddress.Broadcast, Port));

        socketReceive = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socketReceive.EnableBroadcast = true;

        socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port));
    }

    public void Start()
    {
        Console.WriteLine("Agent started!");

        receiving = true;
        receiveThread = new Thread(new ThreadStart(Receive));
        receiveThread.IsBackground = true;
        receiveThread.Start();
    }

    public void Stop()
    {
        receiving = false;

        socketSend.Close();
        socketReceive.Close();

        receiveThread.Join();

        Console.WriteLine("Agent ended.");
    }

    public void Send(string message)
    {
        Console.WriteLine("Sending : {0}", message);
        byte[] bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, Encoding.Unicode.GetBytes(message));
        socketSend.Send(bytes);
        Console.WriteLine("Message sent.");
    }

    protected void Receive()
    {
        Console.WriteLine("Thread started!");
        while (receiving)
        {
            try
            {
                if (socketReceive.Available > 0)
                {
                    byte[] bytes = new byte[socketReceive.Available];

                    Console.WriteLine("Waiting for receive...");

                    int bytesReceived = socketReceive.Receive(bytes, SocketFlags.None);
                    Console.WriteLine("Bytes received : {0}", bytesReceived);

                    string message = Encoding.UTF8.GetString(bytes);
                    Console.WriteLine("Received message : {0}", message);
                    OnMessage(message);
                }
                else
                {
                    Console.Write(".");
                    Thread.Sleep(200);
                }
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.Interrupted)
                {
                    break;
                }
                else
                {
                    throw;
                }
            }
        }
        Console.WriteLine("Thread ended.");
    }
}

私が抱えている問題は、データを1回(ボタンをクリックしたときに)送信しますが、予想される2倍の量を受信することです。たとえば、通常の日付/時刻は19バイトの長さですが、最初に使用可能が0より大きい場合、その値は38です。後続のReceive呼び出しは19バイトのみを取得し、ループは次の19バイトに続きます。つまり、メッセージを2回受信し、もちろん1回だけ受信したいということです。

出力の例:

Agent started!
Thread started!
..........Sending : 29/07/2009 12:05:04
Message sent.
Waiting for receive...
Bytes received : 19
Received message : 29/07/2009 12:05:04
Waiting for receive...
Bytes received : 19
Received message : 29/07/2009 12:05:04
......Thread ended.
Agent ended.
4

2 に答える 2

4
socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port));

すべてのIPアドレスにバインドすることで、ローカルループバックを取得し、ネットワーク経由でも取得できます。

于 2009-07-29T10:12:39.030 に答える
0

最初に、指定されたターゲットIPでこれを試すことをお勧めします。このようにすると、ネットワークトポロジの影響が少なくなり、すべてが期待どおりに機能するときに、ネットワークトポロジをブロードキャストアドレスに移動できます。

于 2009-07-29T10:10:37.410 に答える