제목에 C#의 UDP에 문제가 있다고합니다. DayZ 게임의 rcon 프로토콜 라이브러리를 빌드하려고합니다.모든 패킷이 도착했지만 C# UDP 패킷 손실 (WireShark)
내 문제는 내가 받아야하는 모든 패킷을받지 못한다는 것입니다. 명령을 보낸 후 서버는 분할 답변으로 응답합니다. 패킷 헤더는 총 패킷 수와 현재 패킷의 인덱스를 포함합니다. 이제 17 패킷을 얻으려면 내 응용 프로그램에서 8-15 패킷 만 얻습니다.
WireShark로 테스트 한 후에 모든 패키지가 내 컴퓨터에 도착했음을 알았습니다. 그들은 단지 내 응용 프로그램이나 그와 비슷한 것으로 인식되지 않습니다.
내 실제 질문은 다음과 같습니다 는 내 네트워크 카드와 내 응용 프로그램 사이의 패키지를 잃는 것을 방지 할 수 있습니까? 또는 왜 그런 일이 발생합니까?
다음은 현재 코드입니다. 그것의 아주 더러운 나는 예상대로 작동하지 않다가 떨어져 찢어 때문에 :
private Socket _udpClient;
private Thread _receiverThread;
private Thread _workerThread;
private Queue<byte[]> _packetQueue;
private PacketBuffer[] MessageBuffer;
private byte SenderSequence = 0;
private IPEndPoint connection;
public RCon(IPAddress ip, int port)
{
connection = new IPEndPoint(ip, port);
_udpClient = new Socket(connection.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
_udpClient.Connect(connection);
MessageBuffer = new PacketBuffer[256];
_packetQueue = new Queue<byte[]>();
_receiverThread = new Thread(new ThreadStart(ReceiveCallback));
_receiverThread.IsBackground = true;
_receiverThread.Priority = ThreadPriority.AboveNormal;
_receiverThread.Start();
_workerThread = new Thread(new ThreadStart(WorkerCallback));
_workerThread.IsBackground = true;
_workerThread.Start();
}
public void Login(string password)
{
LoginPacket packet = new LoginPacket(password);
_udpClient.Send(packet.Bytes);
}
public void SendCommand(string command)
{
CommandPacket packet = new CommandPacket(SenderSequence, command);
SenderSequence++;
_udpClient.Send(packet.Bytes);
}
private void ReceiveCallback()
{
while (true)
{
byte[] buffer = new byte[1036];
if (_udpClient.Receive(buffer) > 0)
_packetQueue.Enqueue(buffer);
}
}
private void WorkerCallback()
{
while (true)
{
if (_packetQueue.Count > 0)
{
byte[] buffer = _packetQueue.Dequeue();
if (buffer != null)
{
try
{
Packet receivedPacket = Packet.ParseIncoming(buffer);
OnPacketReceived(new PacketReceivedEventArgs(receivedPacket));
switch (receivedPacket.Type)
{
case PacketType.Message:
OnMessageReceived(new MessageReceivedEventArgs(receivedPacket.Content));
MessageCallbackPacket packet = new MessageCallbackPacket(receivedPacket.SequenceNumber);
_udpClient.Send(packet.Bytes);
break;
case PacketType.CommandCallback:
if (MessageBuffer[receivedPacket.SequenceNumber] == null)
MessageBuffer[receivedPacket.SequenceNumber] = new PacketBuffer(receivedPacket);
else
MessageBuffer[receivedPacket.SequenceNumber].AddPacket(receivedPacket);
if (MessageBuffer[receivedPacket.SequenceNumber].IsComplete)
OnCommandCallback(new CommandCallbackEventArgs(MessageBuffer[receivedPacket.SequenceNumber].GetContent()));
break;
}
}
catch (ArgumentException) { }
catch (OverflowException) { }
catch (FormatException) { }
}
}
}
}
나는 지적인 사람들이 얼마나 많은 사람들이 "느슨한"것이 "잃어 버리는"것과 같은 단어가 아닌지 모를 때 항상 놀란다. –
영어 지식 향상에 도움을 주셔서 감사합니다. – Swarley
'_udpClient.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, 0x40000과 같은 큰 값); –