C++/Win32

[Win32] Windows Socket 기초 - recv 무한 대기 방지

powergirl 2025. 12. 27. 13:45
recv 타임아웃
setsockopt + SO_RCVTIMEO
int timeout = 5000; // 5초
setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

5초동안 데이터 안 오면 recv() 실패 / 반환값 : SOCKET_ERROR

WSAGetLstError() >> WSAETIMEDOUT

 

 

클라이언트 정보 출력
inet_ntoa(clientAddr.sin_addr);
ntohs(clientAddr.sin_port);

 

 

recv 반환값
int ret = recv(clientSocket, (char*)&value, sizeof(int), 0);

ret > 0 : 받은 바이트 수

ret == 0 : 상대방 정상 종료

ret < 0 : 오류

 

 

 

서버
// SB003_Server.cpp
#include <winsock2.h>
#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")

int main()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN serverAddr = {};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(9000);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    bind(listenSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
    listen(listenSocket, SOMAXCONN);

    printf("서버 시작\n");

    while (true)
    {
        SOCKADDR_IN clientAddr = {};
        int addrSize = sizeof(clientAddr);
        SOCKET clientSocket = accept(listenSocket, (SOCKADDR*)&clientAddr, &addrSize);

        printf("접속: %s:%d\n",
               inet_ntoa(clientAddr.sin_addr),
               ntohs(clientAddr.sin_port));

        int timeout = 5000;
        setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO,
                   (char*)&timeout, sizeof(timeout));

        while (true)
        {
            int value = 0;
            int ret = recv(clientSocket, (char*)&value, sizeof(int), 0);

            if (ret > 0)
            {
                printf("수신 값: %d\n", value);
            }
            else if (ret == 0)
            {
                printf("클라이언트 연결 종료\n");
                break;
            }
            else
            {
                int err = WSAGetLastError();
                if (err == WSAETIMEDOUT)
                {
                    printf("수신 타임아웃\n");
                    continue;
                }
                else
                {
                    printf("recv 에러: %d\n", err);
                    break;
                }
            }
        }

        closesocket(clientSocket);
        printf("클라이언트 소켓 닫힘\n");
    }

    closesocket(listenSocket);
    WSACleanup();
    return 0;
}

 

 

 

'C++ > Win32' 카테고리의 다른 글

[Win32] IOCP 서버  (0) 2025.12.27
[Win32] select 서버  (0) 2025.12.27
[Win32] 네트워크 메시지 경계 처리 - Length Prefix  (0) 2025.12.27
[Win32] 서버 확장 : Thread 도입  (0) 2025.12.27
[Win32] Windows Socket 기초 - TCP 연습  (0) 2025.12.27