【问题标题】:Help with Silverlight Sockets and Message deliverySilverlight 套接字和消息传递方面的帮助
【发布时间】:2010-04-23 14:28:01
【问题描述】:

我停止开发 Silverlight 多人国际象棋游戏已有 4 个月了。

alt text http://img408.imageshack.us/img408/8355/chess.gif

问题是我无法重现的错误。我很伤心,因为这是一个测试,如果成功,许多 Silverlight 多人游戏将会出现。互联网上没有关于如何做这样的事情的例子,更不用说只有少数人在他们的编程生活中使用 Sockets。

由于这周我有一些空闲时间,我设法发现了问题,现在我能够重现该错误。

似乎如果我从客户端发送 10 条消息,一个接一个,它们之间没有延迟,就像在下面的示例中一样

// when I press Enter, the client will 10 messages with no delay between them
private void textBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter && textBox.Text.Length > 0)
    {
        for (int i = 0; i < 10; i++)
        {
            MessageBuilder mb = new MessageBuilder();
            mb.Writer.Write((byte)GameCommands.NewChatMessageInTable);
            mb.Writer.Write(string.Format("{0}{2}: {1}", ClientVars.PlayerNickname, textBox.Text, i));
            SendChatMessageEvent(mb.GetMessage());

            //System.Threading.Thread.Sleep(100);
        }

        textBox.Text = string.Empty;
    }
}

    // the method used by client to send a message to server
    public void SendData(Message message)
    {
        if (socket.Connected)
        {
            SocketAsyncEventArgs myMsg = new SocketAsyncEventArgs();
            myMsg.RemoteEndPoint = socket.RemoteEndPoint;
            byte[] buffer = message.Buffer;
            myMsg.SetBuffer(buffer, 0, buffer.Length);

            socket.SendAsync(myMsg);
        }
        else
        {
            string err = "Server does not respond. You are disconnected.";
            socket.Close();
            uiContext.Post(this.uiClient.ProcessOnErrorData, err);
        }
    }

    // the method used by server to receive data from client
    private void OnDataReceived(IAsyncResult async)
    {
        ClientSocketPacket client = async.AsyncState as ClientSocketPacket;
        int count = 0;
        try
        {
            if (client.Socket.Connected)
                count = client.Socket.EndReceive(async);
            // THE PROBLEM IS HERE
            // IF SERVER WAS RECEIVE ALL MESSAGES SEPARATELY, ONE BY ONE, THE COUNT
            // WAS ALWAYS 15, BUT BECAUSE THE SERVER RECEIVE 3 MESSAGES IN 1, THE COUNT
            // IS SOMETIME 45
        }
        catch 
        {
            HandleException(client);
        }

        client.MessageStream.Write(client.Buffer, 0, count);

        Message message;

        while (client.MessageStream.Read(out message))
        {
            message.Tag = client;
            ThreadPool.QueueUserWorkItem(new WaitCallback(this.processingThreadEvent.ServerGotData), message);
            totalReceivedBytes += message.Buffer.Length;
        }

        try
        {
            if (client.Socket.Connected)
                client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, 0, new AsyncCallback(OnDataReceived), client);
        }
        catch 
        {
            HandleException(client);
        }
    }

只发送了 3 条大消息,而每条大消息包含 3 或 4 条小消息。这不是我想要的行为。

如果我在消息传递之间设置了 100 毫秒的延迟,一切正常,但在现实世界的场景中,用户甚至可以在消息传递之间的 1 毫秒之间向服务器发送消息。

  1. 是否需要进行任何设置以使客户端一次只发送一条消息,或者
  2. 即使我在 1 中收到 3 条消息,它们是否一直都是完整的消息(我不想在一条大消息中收到 2.5 条消息)?因为如果它们是,我可以阅读它们并处理这种新情况

【问题讨论】:

    标签: silverlight sockets


    【解决方案1】:

    您错过了 TCP 的主要功能 - 它不是基于消息的协议。它通过单个“管道”发送所有数据。当您将 5 杯水放入管道时,另一端会得到一桶水,而不是 5 杯。如果你足够快地把水从桶里拿出来,你可以得到 5 杯或 10 个半杯或一个桶。与 TCP 相同。如果需要消息,则必须在每条消息的开头和结尾放置一些标记,并在接收端解析流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多