わかりました。助けが必要です。信頼性を必要とするパケットが送信されると、ReliabilityLayerに渡されます。そこから、ReliabilityLayerはそのパケットをリストに追加し、SocketLayerに1回書き込みます。次に、ReliabilityLayerは、2つのタイマーを持つスレッドを生成します。パケットがまだリストにある間、最初のタイマーは250msごとにパケットをSocketLayerに継続的に送信します。2番目のタイマーはタイムアウト時間です。2秒後に例外をスローします。信頼性レイヤーはパケット受信イベントにフックし、信頼性レイヤーパケットリスト内のパケットのチェックサムを含むACKパケットが戻ってきたら、それを削除してスレッドを終了できるようにする必要があります。問題はマルチスレッドです...スレッド間でリストにアクセスすると、ランダムなnullポインターやその他の問題が発生します。だから私はそれをどうにかしてスレッドセーフにするか、この全体を再考する必要があります。誰かが私を助けることができるかどうか疑問に思いましたか?ありがとう
public void Write(NetworkPacket packet, ClientInfo client, Action<byte[], EndPoint> action)
{
if (CSL)
throw new Exception("ReliabilityLayer loaded for client use.");
if (!packet.Command.RequiresReliability())
throw new ArgumentException("Packet does not require reliability.");
//Add the packet to the reliability list
packetList.Add(packet);
//Send the packet to the socket layer.
action.Invoke(packet.RawData, client.EndPoint);
new Thread(() =>
{
Stopwatch timeout = new Stopwatch();
Stopwatch timer = new Stopwatch();
timer.Start();
timeout.Start();
while (packetList.Contains(packet))
{
//Still no response from the remote connection -> send another packet
if (timer.ElapsedMilliseconds > 256)
{
action.Invoke(packet.RawData, client.EndPoint);
timer.Restart();
}
//No response after 2 seconds -> throw exception
if (timeout.ElapsedMilliseconds > 2048)
{
throw new Exception("Client has not responded to the request.");
}
}
}).Start();
}
private void ssl_OnPacketReceived(object sender, ServerPacketEventArgs e)
{
if (e.Packet.Command != Command.Ack)
return;
//Find matching packet in the packetList
NetworkPacket packet = packetList.Find(pkt => pkt.Checksum == e.Packet.Data[0]); //e.Packet.Data[0] is the checksum of the packet that was send out.
if (packet != null)
{
//Remove it to allow thread to exit
packetList.Remove(packet);
}
}