소켓 통신을 하는데 있어서 너무 큰 메시지인 경우에 서버에서 한번에 데이터를 수신받지 못할 수 있습니다
문제 발생
클라이언트 측에서 7000 바이트가 넘는 데이터를 전송해야 하는 상황이 발생하였습니다.
해결 방법
서버 측에서는 큰 데이터를 한번에 받을 수 없기에 나눠서 받아 해당 데이터를 누적시켜 처리하는 방법을 선택해야 했습니다.
클라이언트 측에서는 데이터의 마지막 끝단에 개행 문자를 삽입하여 메시지의 끝을 서버가 알 수 있도록 하였으며
private func sendJSONMessage(_ message: SocketModel) {
do {
var data = try JSONEncoder().encode(message)
if let newlineData = "\n".data(using: .utf8) {
data.append(newlineData)
}
sendMessage(data)
} catch {
print("Failed to encode message: \(error)")
}
}
서버 측에서는 데이터에 '\n' 개행문자가 존재하는지 여부를 확인하고 존재하면 누적된 데이터를 처리할 수 있도록 만들 수 있습니다.
물론 개행문자가 아닌 특정 다른 문자열 또는 조건을 사용하여 문제를 해결할 수도 있습니다.
private static async Task HandleClientAsync(TcpClient client)
{
var stream = client.GetStream();
var buffer = new byte[1024];
var receivedData = new List<byte>();
try
{
while (client.Connected)
{
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
receivedData.AddRange(buffer.Take(bytesRead));
int newlineIndex;
while ((newlineIndex = receivedData.IndexOf((byte)'\n')) != -1)
{
var messageBytes = receivedData.Take(newlineIndex).ToArray();
receivedData.RemoveRange(0, newlineIndex + 1);
var message = Encoding.UTF8.GetString(messageBytes);
Console.WriteLine($"Received from client: {message}");
await HandleMessageAsync(client, message);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error handling client: {ex.Message}");
}
finally
{
RemoveClient(client);
}
}