我遇到的问题是,一个带有byte [20]的对象被传递到一个线程上的BlockingCollection,另一个线程使用BlockingCollection.Take()返回一个带有byte [0]的对象。我认为这是一个线程问题,但考虑到BlockingCollection是一个并发集合,我不知道在哪里或为什么会发生这种情况。
有时在thread2上,myclass2.mybytes等于byte [0]。任何有关如何解决此问题的信息都非常感谢。
[编辑]原始代码。 我删除了上面似乎运行得很好的代码,所以我花时间浏览原始代码并发布。
MessageBuffer.cs
public class MessageBuffer : BlockingCollection<Message>
{
}
在具有Listener()和ReceivedMessageHandler(对象messageProcessor)的类中
private MessageBuffer RecievedMessageBuffer;
在Thread1上
private void Listener()
{
while (this.IsListening)
{
try
{
Message message = Message.ReadMessage(this.Stream, this);
if (message != null)
{
this.RecievedMessageBuffer.Add(message);
}
}
catch (IOException ex)
{
if (!this.Client.Connected)
{
this.OnDisconnected();
}
else
{
Logger.LogException(ex.ToString());
this.OnDisconnected();
}
}
catch (Exception ex)
{
Logger.LogException(ex.ToString());
this.OnDisconnected();
}
}
}
Message.ReadMessage(NetworkStream流,iTcpConnectClient客户端)
public static Message ReadMessage(NetworkStream stream, iTcpConnectClient client)
{
int ClassType = -1;
Message message = null;
try
{
ClassType = stream.ReadByte();
if (ClassType == -1)
{
return null;
}
if (!Message.IDTOCLASS.ContainsKey((byte)ClassType))
{
throw new IOException("Class type not found");
}
message = Message.GetNewMessage((byte)ClassType);
message.Client = client;
message.ReadData(stream);
if (message.Buffer.Length < message.MessageSize + Message.HeaderSize)
{
return null;
}
}
catch (IOException ex)
{
Logger.LogException(ex.ToString());
throw ex;
}
catch (Exception ex)
{
Logger.LogException(ex.ToString());
//throw ex;
}
return message;
}
在Thread2上
private void ReceivedMessageHandler(object messageProcessor)
{
if (messageProcessor != null)
{
while (this.IsListening)
{
Message message = this.RecievedMessageBuffer.Take();
message.Reconstruct();
message.HandleMessage(messageProcessor);
}
}
else
{
while (this.IsListening)
{
Message message = this.RecievedMessageBuffer.Take();
message.Reconstruct();
message.HandleMessage();
}
}
}
PlayerStateMessage.cs
public class PlayerStateMessage : Message
{
public GameObject PlayerState;
public override int MessageSize
{
get { return 12; }
}
public PlayerStateMessage()
: base()
{
this.PlayerState = new GameObject();
}
public PlayerStateMessage(GameObject playerState)
{
this.PlayerState = playerState;
}
public override void Reconstruct()
{
this.PlayerState.Poisiton = this.GetVector2FromBuffer(0);
this.PlayerState.Rotation = this.GetFloatFromBuffer(8);
base.Reconstruct();
}
public override void Deconstruct()
{
this.CreateBuffer();
this.AddToBuffer(this.PlayerState.Poisiton, 0);
this.AddToBuffer(this.PlayerState.Rotation, 8);
base.Deconstruct();
}
public override void HandleMessage(object messageProcessor)
{
((MessageProcessor)messageProcessor).ProcessPlayerStateMessage(this);
}
}
Message.GetVector2FromBuffer(int bufferlocation) 这是抛出异常的地方,因为当它应该是byte [20]时,this.Buffer是byte [0]。
public Vector2 GetVector2FromBuffer(int bufferlocation)
{
return new Vector2(
BitConverter.ToSingle(this.Buffer, Message.HeaderSize + bufferlocation),
BitConverter.ToSingle(this.Buffer, Message.HeaderSize + bufferlocation + 4));
}
答案 0 :(得分:0)
所以这是一个难以解决的问题。据我所知,我只是接收随机字节,所以我改变了我的“消息”相当多。现在有一个头缓冲区和一个数据缓冲区。整个消息用开始标记和结束标记封装,而标题和数据缓冲区每个都用不同的标记封装。这让我可以告诉我何时收到了错误的数据,并且可以丢弃该消息。如果消息确实被丢弃,则在下一条消息读取时,不是仅检查接收的前4个字节是否为开始标记,而是逐字节读取,直到读取的最后4个字节等于标记。