bind 함수(winsock.h)

bind 함수는 로컬 주소를 소켓과 연결합니다.

구문

int bind(
  [in] SOCKET         s,
       const sockaddr *addr,
  [in] int            namelen
);

매개 변수

[in] s

언바운드 소켓을 식별하는 설명자입니다.

addr

바인딩된 소켓 에 할당할 로컬 주소의 sockaddr 구조체에 대한 포인터입니다.

[in] namelen

addr가 가리키는 값의 길이(바이트)입니다.

반환 값

오류가 발생하지 않으면 bind 는 0을 반환합니다. 그렇지 않으면 SOCKET_ERROR 반환하고 WSAGetLastError를 호출하여 특정 오류 코드를 검색할 수 있습니다.

오류 코드 의미
WSANOTINITIALISED
참고 이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다.
 
WSAENETDOWN
네트워크 하위 시스템이 실패했습니다.
WSAEACCES
액세스 권한에 의해 금지된 방식으로 소켓에 액세스하려고 시도했습니다.

이 오류는 setockopt 옵션 SO_BROADCAST 사용하도록 설정되지 않아 nn이 브로드캐스트 주소에 데이터그램 소켓을 바인딩하지 못한 경우 반환됩니다.

WSAEADDRINUSE
각 소켓 주소(프로토콜/네트워크 주소/포트)는 한 가지 사용만 허용됩니다.

이 오류는 컴퓨터의 프로세스가 이미 동일한 정규화된 주소에 바인딩되어 있고 소켓이 SO_REUSEADDR 주소 재사용을 허용하도록 표시되지 않은 경우 반환됩니다. 예를 들어 이름 매개 변수에 지정된 IP 주소 및 포트는 이미 다른 애플리케이션에서 사용하는 다른 소켓에 바인딩되어 있습니다. 자세한 내용은 SOL_SOCKET 소켓 옵션 참조, SO_REUSEADDR 및 SO_EXCLUSIVEADDRUSE 사용 및 SO_EXCLUSIVEADDRUSE SO_REUSEADDR소켓 옵션을 참조하세요.

WSAEADDRNOTAVAIL
요청한 주소가 해당 컨텍스트에서 잘못되지 않음

이름 매개 변수 가 가리키는 지정된 주소가 이 컴퓨터의 유효한 로컬 IP 주소가 아닌 경우 이 오류가 반환됩니다.

WSAEFAULT
시스템이 호출에서 포인터 인수를 사용하려는 시도에서 잘못된 포인터 주소를 발견했습니다.

이름 매개 변수가 NULL이고, 이름 또는 namelen 매개 변수가 사용자 주소 공간의 유효한 부분이 아니거나, namelen 매개 변수가 너무 작거나, name 매개 변수에 연결된 주소 패밀리의 주소 형식이 잘못되었거나, 이름으로 지정된 메모리 블록의 처음 2바이트가 소켓 설명자 s와 연결된 주소 패밀리와 일치하지 않는 경우 이 오류가 반환됩니다.

WSAEINPROGRESS
차단 Windows 소켓 1.1 호출이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다.
WSAEINVAL
잘못된 인수가 지정되었습니다.

이 오류는 이미 주소에 바인딩된 소켓 반환됩니다.

WSAENOBUFS
일반적으로 WSAENOBUFS 는 바인딩에 할당할 임시 포트가 충분하지 않다는 것을 나타냅니다.
WSAENOTSOCK
소켓이 아닌 항목에서 작업을 시도했습니다.

이 오류는 s 매개 변수 설명자가 소켓이 아닌 경우 반환됩니다.

설명

바인딩 함수는 수신 대기 함수에 대한 후속 호출 전에 연결되지 않은 소켓에 필요합니다. 일반적으로 연결 지향(스트림) 또는 연결 없는(데이터그램) 소켓에 바인딩하는 데 사용됩니다. 바인딩 함수를 사용하여 원시 소켓에 바인딩할 수도 있습니다(소켓은 형식 매개 변수가 SOCK_RAW 설정된 소켓 함수를 호출하여 생성됨). 바인딩 함수는 연결되지 않은 소켓에서 연결되지 않은 소켓에서 연결되지 않은 후 ConnectEx, WSAConnect, WSAConnectByList 또는 WSAConnectByName 함수를 보내기 전에 사용할 수도 있습니다.

소켓 함수를 호출하여 소켓 을 만들면 네임스페이스(주소 패밀리)에 존재하지만 이름이 할당되지 않습니다. 바인딩 함수를 사용하여 이름 없는 소켓에 로컬 이름을 할당하여 소켓의 로컬 연결을 설정합니다.

이름은 인터넷 주소 패밀리를 사용할 때 세 부분으로 구성됩니다.

  • 주소 패밀리입니다.
  • 호스트 주소입니다.
  • 애플리케이션을 식별하는 포트 번호입니다.

Windows 소켓 2에서 이름 매개 변수는 sockaddr 구조체에 대한 포인터로 엄격하게 해석되지 않습니다. Windows 소켓 1.1 호환성을 위해 이러한 방식으로 캐스팅됩니다. 서비스 공급자는 namelen 크기의 메모리 블록에 대한 포인터로 간주할 수 있습니다. 이 블록의 처음 2바이트(sockaddr 구조체의 sa_family 멤버, sockaddr_in 구조의 sin_family 멤버 또는 sockaddr_in6 구조체의 sin6_family 멤버에 해당)에는 소켓을 만드는 데 사용된 주소 패밀리 가 포함되어야 합니다. 그렇지 않으면 WSAEFAULT 오류가 발생합니다.

애플리케이션이 할당된 로컬 주소를 신경 쓰지 않는 경우 IPv4 로컬 주소에 대한 상수 값 INADDR_ANY 또는 이름 매개 변수의 sa_data 멤버에서 IPv6 로컬 주소에 대한 상수 값 in6addr_any 지정합니다. 이렇게 하면 기본 서비스 공급자가 적절한 네트워크 주소를 사용할 수 있으므로 다중 호스트 (즉, 둘 이상의 네트워크 인터페이스와 주소가 있는 호스트)가 있는 상태에서 애플리케이션 프로그래밍을 간소화할 수 있습니다.

TCP/IP의 경우 포트가 0으로 지정된 경우 서비스 공급자는 동적 클라이언트 포트 범위에서 애플리케이션에 고유한 포트를 할당합니다. Windows Vista 이상에서는 동적 클라이언트 포트 범위가 49152에서 65535 사이의 값입니다. 이는 동적 클라이언트 포트 범위가 1025에서 5000 사이의 값이었던 Windows Server 2003 이전의 변경 내용입니다. 클라이언트 동적 포트 범위의 최대값은 다음 레지스트리 키에서 값을 설정하여 변경할 수 있습니다.

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

MaxUserPort 레지스트리 값은 동적 클라이언트 포트 범위의 최대값에 사용할 값을 설정합니다. 이 설정을 적용하려면 컴퓨터를 다시 시작해야 합니다.

Windows Vista 이상에서는 netsh 명령을 사용하여 동적 클라이언트 포트 범위를 보고 변경할 수 있습니다. 동적 클라이언트 포트 범위는 UDP 및 TCP와 IPv4 및 IPv6에 대해 다르게 설정할 수 있습니다. 자세한 내용은 KB 929851 참조하세요.

애플리케이션은 바인딩을 호출한 후 getsockname을 사용하여 소켓에 할당된 주소와 포트를 학습할 수 있습니다. 인터넷 주소가 INADDR_ANY 또는 in6addr_any 동일한 경우 호스트가 다중 호스트인 경우 여러 주소가 유효할 수 있으므로 소켓이 연결될 때까지 getsockname 에서 반드시 주소를 제공할 수 없습니다. 로컬 컴퓨터에서 이미 해당 포트 번호를 사용하여 다른 소켓과 충돌할 위험이 있으므로 클라이언트 애플리케이션에서는 포트 0 이외의 특정 포트 번호에 바인딩하는 것이 좋습니다.

참고 SO_EXCLUSIVEADDRUSE 또는 SO_REUSEADDR 소켓 옵션과 함께 바인딩 을 사용하는 경우 영향을 미치려면 바인딩 을 실행하기 전에 소켓 옵션을 설정해야 합니다. 자세한 내용은 SO_EXCLUSIVEADDRUSESO_REUSEADDR 및 SO_EXCLUSIVEADDRUSE 사용을 참조하세요.

 

멀티캐스트 작업의 경우 기본 방법은 bind 함수를 호출하여 소켓을 로컬 IP 주소와 연결한 다음 멀티캐스트 그룹에 조인하는 것입니다. 이 작업 순서는 필수는 아니지만 강력히 권장됩니다. 따라서 멀티캐스트 애플리케이션은 먼저 로컬 컴퓨터에서 IPv4 또는 IPv6 주소, 와일드카드 IPv4 주소(INADDR_ANY) 또는 와일드카드 IPv6 주소(in6addr_any)를 선택합니다. 그런 다음 멀티캐스트 애플리케이션은 name 매개 변수의 sa_data 멤버에서 이 주소를 사용하여 bind 함수를 호출하여 로컬 IP 주소를 소켓과 연결합니다. 와일드카드 주소를 지정한 경우 Windows에서 사용할 로컬 IP 주소를 선택합니다. 바인딩 함수가 완료되면 애플리케이션이 관심 있는 멀티캐스트 그룹에 조인합니다. 멀티캐스트 그룹에 조인하는 방법에 대한 자세한 내용은 멀티캐스트 프로그래밍 섹션을 참조하세요. 그런 다음, 이 소켓을 사용하여 recv, recvfrom, WSARecv, WSARecvEx, WSARecvFrom 또는 LPFN_WSARECVMSG(WSARecvMsg) 함수를 사용하여 멀티캐스트 그룹에서 멀티캐스트 패킷을 받을 수 있습니다.

바인딩 함수는 일반적으로 멀티캐스트 그룹에 작업을 보내는 데 필요하지 않습니다. 소켓이 아직 바인딩되지 않은 경우 sendto, WSASendMsgWSASendTo 함수는 소켓을 와일드카드 주소에 암시적으로 바인딩합니다. 바인딩 함수는 암시적 바인딩을 수행하지 않고 연결된 소켓에서만 허용되는 send 또는 WSASend 함수를 사용하기 전에 필요합니다. 즉, 소켓이 연결되려면 이미 바인딩되어 있어야 합니다. 애플리케이션이 여러 네트워크 인터페이스 및 로컬 IP 주소가 있는 로컬 컴퓨터에서 특정 로컬 IP 주소를 선택하려는 경우 sendto, WSASendMsg 또는 WSASendTo 함수를 사용하여 작업을 보내기 전에 바인딩 함수를 사용할 수 있습니다. 그렇지 않으면 sendto, WSASendMsg 또는 WSASendTo 함수를 사용하여 와일드카드 주소에 암시적으로 바인딩하면 보내기 작업에 다른 로컬 IP 주소가 사용될 수 있습니다.

참고바인딩과 같은 차단 Winsock 호출을 실행할 때 Winsock은 호출이 완료되기 전에 네트워크 이벤트를 기다려야 할 수 있습니다. Winsock은 이 상황에서 경고 가능한 대기를 수행하며, 동일한 스레드에서 예약된 APC(비동기 프로시저 호출)에 의해 중단될 수 있습니다. 동일한 스레드에서 지속적인 차단 Winsock 호출을 중단한 APC 내에서 또 다른 차단 Winsock 호출을 실행하면 정의되지 않은 동작이 발생하며 Winsock 클라이언트에서 시도해서는 안 됩니다.
 

IrDA 소켓에 대한 참고 사항

  • Af_irda.h 헤더 파일은 명시적으로 포함되어야 합니다.
  • 로컬 이름은 IrDA에 노출되지 않습니다. 따라서 IrDA 클라이언트 소켓은 connect 함수 전에 bind 함수를 호출해서는 안 됩니다. 이전에 바인딩을 사용하여 IrDA 소켓이 서비스 이름에 바인딩된 경우 연결 함수는 SOCKET_ERROR 실패합니다.
  • 서비스 이름이 "LSAP-SELxxx" 형식인 경우 여기서 xxx는 1-127 범위의 10진수 정수이며 주소는 서비스 이름이 아닌 특정 LSAP-SEL xxx를 나타냅니다. 이와 같은 서비스 이름을 사용하면 서버 애플리케이션이 먼저 ISA 서비스 이름 쿼리를 수행하지 않고 특정 LSAP-SEL로 전달되는 들어오는 연결을 수락하여 연결된 LSAP-SEL을 가져올 수 있습니다. 이 서비스 이름 유형의 한 가지 예는 IAS를 지원하지 않는 비 Windows 디바이스입니다.

Windows Phone 8: 이 함수는 Windows Phone 8 이상에서 Windows Phone 스토어 앱에서 지원됩니다.

Windows 8.1Windows Server 2012 R2: 이 함수는 Windows 8.1, Windows Server 2012 R2 이상에서 Windows 스토어 앱에서 지원됩니다.

예제

다음 예제에서는 bind 함수를 사용하는 방법을 보여 줍니다. bind 함수를 사용하는 또 다른 예제는 시작 With Winsock을 참조하세요.

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int main()
{

    // Declare some variables
    WSADATA wsaData;

    int iResult = 0;            // used to return function results

    // the listening socket to be created
    SOCKET ListenSocket = INVALID_SOCKET;

    // The socket address to be passed to bind
    sockaddr_in service;

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"Error at WSAStartup()\n");
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for 
    // incoming connection requests
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket function failed with error: %u\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port for the socket that is being bound.
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);

    //----------------------
    // Bind the socket.
    iResult = bind(ListenSocket, (SOCKADDR *) &service, sizeof (service));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"bind failed with error %u\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    else
        wprintf(L"bind returned success\n");

    WSACleanup();
    return 0;
}

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows 8.1, Windows Vista [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 winsock.h(Winsock2.h 포함)
라이브러리 Ws2_32.lib
DLL Ws2_32.dll

추가 정보

멀티캐스트 프로그래밍

SOL_SOCKET 소켓 옵션

SO_EXCLUSIVEADDRUSE

TCP/IP 원시 소켓

SO_REUSEADDR 및 SO_EXCLUSIVEADDRUSE 사용

WSACancelBlockingCall

Winsock 함수

Winsock 참조

connect

getsockname

listen

setsockopt

sockaddr

socket