2010-04-23 3 views
2

Прошло 4 месяца с тех пор, как я прекратил разработку моей игры Silverlight Multiplayer Chess.Помощь с разъемами Silverlight и доставкой сообщений

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

Проблема была ошибка которым я не мог воспроизвести. Мне очень грустно, потому что это был тест, и много многопользовательских игр Silverlight придут, если это будет успешным. В Интернете нет примеров того, как делать такие вещи, не говоря уже о том, что лишь немногие люди используют сокеты в своей жизни программирования.

Поскольку на этой неделе я получил некоторое свободное время, мне удалось обнаружить проблему, и теперь я могу воспроизвести ошибку.

кажется, что если я посылаю 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. Если вам нужны сообщения, вы должны поместить некоторые маркеры в начале и в конце каждого сообщения и проанализировать поток на принимающей стороне.

Смежные вопросы