[Unity] TCP통신에서 패킷이 누락되는듯한 문제 수정Unity/TroubleShooting2022. 10. 18. 10:10
Table of Contents
개요
프로젝트에서 PVP구현을 위해 서버통신을 작업하던 중
위치 동기화같이 빠르게 주고받아야 하는 데이터의 패킷들이
일부 누락되는것 처럼 보이는 문제가 발생했다.
(서버는 자바스크립트)
완벽해결은 아니지만 해결방법을 기록한다.
문제
위 설명대로 패킷이 누락되는것처럼
A클라이언트에서 보낸 패킷 일부가 B클라이언트에 도착하지 않았고,
서버쪽에서 디버그를 해봐도 서버에조차 패킷이 도착하지 않았다.
처음엔 통신문제인줄 알아서 여러시도를 해봤지만 전부 아니었고
답은 네이글 알고리즘 때문이었다.
네이글 알고리즘이란
간단히 이해한대로 적어보면
패킷이 만들어지는대로 보내지 않고
패킷을 버퍼에 보관하다가 ACK를 수신하면 나머지 패킷들을 한번에 전송해줘서
결론적으로는 통신량을 줄이는 방법이다.
해결
사실 명쾌한 해결은 시간적으로도 촉박했기때문에 하지못했고 편법으로 네이글 알고리즘 사용을 off해버렸다.
Unity클라이언트 코드에서는 네이글 알고리즘을 대비해서 받은 패킷에대해 사이즈 확인은 아래와 같이 처리했지만
if (readSize > 0)
{
buffRecvSize += readSize;
/*
패킷이 나누어져서 오거나
2개 이상의 패킷이 하나로 올수 있어서 체크한다(네이글 알골리즘)
*/
while (buffRecvSize >= sizeof(int))
{
int packetLength = 0;
packetLength = BitConverter.ToInt32(bufferRecv, 0);
if(buffRecvSize >= packetLength)
{
JsonMessage msgRecv = new JsonMessage();
//msgRecv.buffer = bufferRecv;
Buffer.BlockCopy(bufferRecv, 0, msgRecv.buffer, 0, packetLength);
buffRecvSize -= packetLength;
if(buffRecvSize >= sizeof(int))
{
Buffer.BlockCopy(bufferRecv, packetLength, bufferRecv, 0, buffRecvSize);
}
// 암호화했다면 이 사이에서 복호화
msgRecv.ReadEnd();
Debug.LogFormat("받은 데이터: {0}", msgRecv.jsonBuffer.ToString(Newtonsoft.Json.Formatting.Indented));
lock (csReceive)
{
// 클라 쓰레드로 전달
queueReceive.Enqueue(msgRecv);
}
}
else
{
// 온전한 패킷을 구성하기에 충분한 데이터가 없음. loop를 빠져나간다.
break;
}
}
}
발신이 안돼버리는 경우는 미리 대처를 하지못하였다.
그래서 네이글 알고리즘을 끄는방법은
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(GameURL.PVP_IP, GameURL.PVP_PORT);
.
.
.
socket.NoDelay = true;
소켓 클래스의 NoDelay를 true로 바꿔주는것.
이 설명대로 true로 바꿔주면 네이글 알고리즘을 사용하지 않는다는 것이다.
즉 패킷이 클라이언트에서 만들어 지는대로 바로바로 보내게 되는것
기본값은 false이기때문에 따로 설정하지않으면 네이글 알고리즘을 사용하는것이다.
결론
이번 시행착오는 아쉽게도 편법으로 해결해버렸다.
시간적 여유가 생기면 꼭 정확한 원인을 찾아볼 예정이다.
'Unity > TroubleShooting' 카테고리의 다른 글
[Unity] Admob사용 시 Screen.Orientation을 건드리면 생기는 문제 (0) | 2023.05.31 |
---|---|
[Firebase] FirebaseAuth 소셜로그인 콜백 주의점 (0) | 2023.05.26 |
[Unity] GoogleSheetsForUnity 에러수정 (0) | 2022.10.13 |
[Unity] RenderTexutre를 PNG로 저장할때 어두워지는 문제 (0) | 2022.08.09 |
AssetDatabase.RenameAsset 함수 주의사항 (1) | 2021.10.14 |