TCP 기반에서 송수신하는 데이터에는 경계가 존재하지 않는다고 하는데, 이는 다음의 의미를 가진다.
"데이터 송수신 과정에서 호출하는 입출력 함수의 호출횟수는 큰 의미를 지니지 않는다."
반대로 UDP는 데이터의 경계가 존재하는 프로토콜이므로, 데이터 송수신 과정에서 호출하는 입출력 함수의 호출횟수가 큰 의미를 지닌다.
때문에 입력 함수의 호출횟수와 출력함수의호출횟수가 완벽히 일치해야 송신된 데이터를 전부 수신할 수 있다.
예를 들어 세번의 출력함수를 통해 전송된 데이터는 반드시 세번의 입력함수 호출이 있어야 데이터를 전부 수신할 수 있다.
아래와 같이 데이터를 받기 까지 5초의 딜레이가 있는 코드가 있다고 하자.
for(i = 0; i<3; i++)
{
sleep(5); // 5초 딜레이
adr_sz = sizeof(your_adr);
str_len = recvfrom(sock, message, BUF_SIZE, 0,
(struct sockaddr*)&your_adr, &adr_sz);
printf("Message %d : %s\n", i + 1, message);
}
close(sock);
return 0;
}
그리고 3번의 데이터를 보내는 함수가 있다.
sendto(sock, msg1, sizeof(msg1), 0, (struct sockaddr*)&your_adr, sizeof(your_adr));
sendto(sock, msg2, sizeof(msg2), 0, (struct sockaddr*)&your_adr, sizeof(your_adr));
sendto(sock, msg3, sizeof(msg3), 0, (struct sockaddr*)&your_adr, sizeof(your_adr));
하지만 데이터를 3번 보내더라도 데이터를 받기까지 5초의 딜레이가 있어서 recvfrom() 함수가 호출되기 이전에 3회의 sendto() 함수 호출이 진행되어서 데이터는 이미 전송된 상태에 놓이게 된다.
그래서 그런거인지는 모르겠지만, 클라이언트에서 foreach문으로 계속해서 list사이즈만큼 데이터를 보내주고,
public static void sendBlockData(string name)
{
byte[] buffer;
foreach(var tile in tileObjectManager.createdTileList)
{
buffer = new byte[1024 * 4];
SEND_DATA send_data = new SEND_DATA();
send_data.packet_Type = (int)PACKET_ID.SEND_BLOCK_DATA;
send_data.playerName = name;
send_data.x = tile.transform.position.x;
send_data.y = tile.transform.position.y;
send_data.z = tile.transform.position.z;
send_data.BlockType = tile.getID;
Serialize(send_data).CopyTo(buffer, 0);
clntSocket.SendTo(buffer, serverEP);
i++;
}
}
서버에서도 while문으로 받은 데이터를 계속 받았는데
while (true)
{
while (srvSocket.ReceiveFrom(buffer, ref clientEP) != 0)
{
Console.WriteLine("받은 데이터 패킷 분석 중...");
i++;
AnalyzePacket(srvSocket, buffer, conn);
Console.WriteLine("데이터 받은 횟수 : " + i);
}
}
클라이언트에서 데이터를 50개 보내면 서버에서는 다 읽지 못하고 절반정도 읽고 더 이상 읽을게 없다며 읽지 않았다.
그래서 클라이언트에 데이터를 보낼 때 텀을 주었더니 또 정상적으로 작동하였다.
Thread.Sleep(500);
'네트워크 프로그래밍' 카테고리의 다른 글
Select Model (0) | 2023.02.20 |
---|---|
TCP vs UDP (0) | 2023.02.20 |
MySql : Commands out of sync; you can't run this command now 에러 (0) | 2022.12.15 |
System.Runtime.Serialization.SerializationException: Unable to find assembly 오류 (0) | 2022.12.11 |
Overlapped I/O 모델 (0) | 2022.08.22 |