accept 函式 (winsock2.h)

accept函式允許通訊端上的連入連線嘗試。

語法

SOCKET WSAAPI accept(
  [in]      SOCKET   s,
  [out]     sockaddr *addr,
  [in, out] int      *addrlen
);

參數

[in] s

描述項,識別已使用 接聽 函式處於接聽狀態的通訊端。 連接實際上是使用 接受所傳回的通訊端進行。

[out] addr

接收連線實體位址之緩衝區的選擇性指標,稱為通訊層。 addr參數的確切格式取決於從sockaddr結構建立通訊端時所建立的位址系列。

[in, out] addrlen

包含 addr 參數所指向之結構長度的整數選擇性指標。

傳回值

如果沒有發生錯誤, accept 會傳回 SOCKET 類型的值,這是新通訊端的描述元。 這個傳回的值是進行實際連接之通訊端的控制碼。

否則,會傳回 INVALID_SOCKET 的值,而且可以呼叫 WSAGetLastError來擷取特定的錯誤碼。

addrlen所參考的整數一開始包含addr所指向的空間量。傳回時,它會包含所傳回位址的實際長度位元組。

錯誤碼 意義
WSANOTINITIALISED
使用此函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAECONNRESET
表示傳入連線,但在接受呼叫之前,遠端對等已終止。
WSAEFAULT
addrlen參數太小,或增益集不是使用者位址空間的有效部分。
WSAEINTR
封鎖的 Windows Sockets 1.1 呼叫已透過 WSACancelBlockingCall取消。
WSAEINVAL
函式在 接受之前未叫用。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或者服務提供者仍在處理回呼函式。
WSAEMFILE
佇列在 要接受 的專案時是無空的,而且沒有描述項可供使用。
WSAENETDOWN
網路子系統失敗。
WSAENOBUFS
沒有可用的緩衝區空間。
WSAENOTSOCK
描述項不是通訊端。
WSAEOPNOTSUPP
參考的通訊端不是支援連接導向服務的型別。
WSAEWOULDBLOCK
通訊端會標示為非封鎖,而且沒有連線可供接受。

備註

accept函式會擷取通訊端上擱置連線佇列上的第一個連線。 然後,它會建立並傳回新通訊端的控制碼。 新建立的通訊端是將處理實際連線的通訊端;其屬性 與通訊端相同,包括向 WSAAsyncSelectWSAEventSelect 函式註冊的非同步事件。

接受函式可以封鎖呼叫端,直到佇列上沒有擱置的連線存在,且通訊端標示為封鎖為止。 如果通訊端標示為非封鎖,且佇列上沒有擱置的連線, 則 accept 會傳回錯誤,如下所述。 成功完成 接受 後,會傳回新的通訊端控制碼之後,就無法使用接受的通訊端來接受更多連線。 原始通訊端會保持開啟狀態,並接聽新的連線要求。

參數 載入器 是填入連線實體位址的結果參數,稱為通訊層。 addr參數的確切格式是由通訊發生的位址系列所決定。 addrlen是 value-result 參數;它一開始應該包含附加元件所指向的空間量;傳回時,它會包含傳回之位址) 以位元組為單位的實際長度 (。

accept函式會與連線導向通訊端類型搭配使用,例如 SOCK_STREAM。 如果 addr 和/或 addrlen 等於 Null,則不會傳回所接受通訊端遠端位址的相關資訊。

注意 發出封鎖的 Winsock 呼叫,例如 accept時,Winsock 可能需要等候網路事件,才能完成呼叫。 Winsock 會在這種情況中執行可警示的等候,而非同步程序呼叫 (APC) 排程在同一個執行緒上,可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同執行緒上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 用戶端嘗試。
 

範例程式碼

下列範例示範 使用 accept 函式。
#ifndef UNICODE
#define UNICODE
#endif

#include <winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <windows.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int wmain(void)
{

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

    if (bind(ListenSocket,
             (SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR) {
        wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //----------------------
    // Listen for incoming connection requests.
    // on the created socket
    if (listen(ListenSocket, 1) == SOCKET_ERROR) {
        wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //----------------------
    // Create a SOCKET for accepting incoming requests.
    SOCKET AcceptSocket;
    wprintf(L"Waiting for client to connect...\n");

    //----------------------
    // Accept the connection.
    AcceptSocket = accept(ListenSocket, NULL, NULL);
    if (AcceptSocket == INVALID_SOCKET) {
        wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    } else
        wprintf(L"Client connected.\n");

    // No longer need server socket
    closesocket(ListenSocket);

    WSACleanup();
    return 0;
}


如需使用accept函式的另一個範例,請參閱使用 Winsock 消費者入門

ATM 的注意事項

以下是與連線設定相關聯的重要問題,而且在使用 Windows Sockets 2 (ATM) 時,必須考慮:

  • acceptWSAAccept函式不一定設定遠端位址和位址長度參數。 因此,使用 ATM 時,呼叫端應該使用WSAAccept函式,並將ATM_CALLING_PARTY_NUMBER_IE放在QoS結構的ProviderSpecific成員中,其本身會包含在根據WSAAccept使用的回呼函式的 lpSQOS參數中。
  • 使用 accept 函式時,請注意,在連線建立之前,函式可能會在傳送者與接收者之間周遊整個距離之前傳回。 這是因為 接受 函式會在收到 CONNECT ACK 訊息時立即傳回;在 ATM 中,連接 ACK 訊息會在路徑中的下一個參數立即傳回 (,而不是最終建立連線的結束節點所傳送的 CONNECT ACK) 。 因此,應用程式應該瞭解,如果在收到 CONNECT ACK 訊息之後立即傳送資料,可能會遺失資料,因為傳送者和接收者之間可能尚未建立連線。

Windows 8.1Windows Server 2012 R2:Windows 市集應用程式支援此函式,Windows 8.1、Windows Server 2012 R2 及更新版本。

規格需求

   
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式|UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式|UWP 應用程式]
目標平臺 Windows
標頭 winsock2.h
程式庫 Ws2_32.lib
DLL Ws2_32.dll

另請參閱

WSAAccept

WSAAsyncSelect

Winsock 函式

Winsock 參考

bind

connect

listen

select

sockaddr

插座