2010-04-23 19 views
2

有4个月以来我停止开发Silverlight的我的多人国际象棋游戏。帮助使用Silverlight插座和消息传递

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

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

由于这周我有一些空闲时间,我成功地发现问题,我现在能够重现bug。

看来,如果我把从客户端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. 即使我收到3条消息在1,他们是完整邮件所有的时间(我不不想在一封大邮件中收到2.5封邮件)?因为如果它们是,我可以阅读它们并对待这种新情况

回答

2

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