Fungsi WSAConnectByList (winsock2.h)

Fungsi WSAConnectByList membuat koneksi ke salah satu dari kumpulan kemungkinan titik akhir yang diwakili oleh sekumpulan alamat tujuan (nama host dan port). Fungsi ini mengambil semua alamat tujuan yang diteruskan ke sana dan semua alamat sumber komputer lokal, dan mencoba menyambungkan menggunakan semua kombinasi alamat yang mungkin sebelum menyerah.

Fungsi ini mendukung alamat IPv4 dan IPv6.

Sintaks

BOOL WSAConnectByList(
  [in]      SOCKET               s,
  [in]      PSOCKET_ADDRESS_LIST SocketAddress,
  [in, out] LPDWORD              LocalAddressLength,
  [out]     LPSOCKADDR           LocalAddress,
  [in, out] LPDWORD              RemoteAddressLength,
  [out]     LPSOCKADDR           RemoteAddress,
  [in]      const timeval        *timeout,
  [in]      LPWSAOVERLAPPED      Reserved
);

Parameter

[in] s

Deskriptor yang mengidentifikasi soket yang tidak terikat dan tidak tersambung. Perhatikan bahwa tidak seperti panggilan Winsock lainnya untuk membuat koneksi (misalnya, WSAConnect), fungsi WSAConnectByList memerlukan soket tidak terikat.

[in] SocketAddress

Penunjuk ke struktur SOCKET_ADDRESS_LIST yang mewakili kemungkinan alamat tujuan dan pasangan port untuk disambungkan ke serekan. Adalah tanggung jawab aplikasi untuk mengisi nomor port di setiap struktur SOCKET_ADDRESS dalam SOCKET_ADDRESS_LIST.

[in, out] LocalAddressLength

Pada input, penunjuk ke ukuran, dalam byte, dari buffer LocalAddress yang disediakan oleh pemanggil. Pada output, pointer ke ukuran, dalam byte, dari SOCKADDR untuk alamat lokal yang disimpan di buffer LocalAddress yang diisi oleh sistem setelah berhasil menyelesaikan panggilan.

[out] LocalAddress

Penunjuk ke struktur SOCKADDR yang menerima alamat lokal koneksi. Ukuran parameter persis dengan ukuran yang dikembalikan di LocalAddressLength. Ini adalah informasi yang sama yang akan dikembalikan oleh fungsi getsockname . Parameter ini dapat berupa NULL, dalam hal ini, parameter LocalAddressLength diabaikan.

[in, out] RemoteAddressLength

Pada input, penunjuk ke ukuran, dalam byte, dari buffer RemoteAddress yang disediakan oleh pemanggil. Pada output, penunjuk ke ukuran, dalam byte, dari SOCKADDR untuk alamat jarak jauh yang disimpan dalam buffer RemoteAddress yang diisi oleh sistem setelah berhasil menyelesaikan panggilan.

[out] RemoteAddress

Penunjuk ke struktur SOCKADDR yang menerima alamat jarak jauh koneksi. Ini adalah informasi yang sama yang akan dikembalikan oleh fungsi getpeername . Parameter ini dapat berupa NULL, dalam hal ini, RemoteAddressLength diabaikan.

[in] timeout

Waktu, dalam milidetik, untuk menunggu respons dari aplikasi jarak jauh sebelum membatalkan panggilan. Parameter ini dapat berupa NULL dalam hal ini WSAConnectByList akan selesai setelah koneksi berhasil dibuat atau setelah koneksi dicoba dan gagal pada semua pasangan alamat lokal-jarak jauh yang mungkin.

[in] Reserved

Dicadangkan untuk implementasi di masa mendatang. Parameter ini harus diatur ke NULL.

Nilai kembali

Jika koneksi dibuat, WSAConnectByList mengembalikan parameter TRUE dan LocalAddress dan RemoteAddress diisi jika buffer ini disediakan oleh pemanggil.

Jika panggilan gagal, FALSE dikembalikan. WSAGetLastError kemudian dapat dipanggil untuk mendapatkan informasi kesalahan yang diperluas.

Menampilkan kode Deskripsi
WSAEHOSTUNREACH
Host lolos sebagai parameter nodename tidak dapat dijangkau.
WSAEINVAL
Parameter yang tidak valid diteruskan ke fungsi. Parameter Yang Dicadangkan harus NULL.
WSAENOBUFS
Memori yang cukup tidak dapat dialokasikan.
WSAENOTSOCK
Soket yang tidak valid diteruskan ke fungsi. Parameter s tidak boleh INVALID_SOCKET atau NULL.
WSAETIMEDOUT
Respons dari aplikasi jarak jauh tidak diterima sebelum parameter batas waktu terlampaui.

Keterangan

WSAConnectByList mirip dengan fungsi WSAConnectByName . Alih-alih mengambil satu nama host dan nama layanan (port), WSAConnectByList mengambil daftar alamat (alamat host dan port) dan terhubung ke salah satu alamat. Fungsi WSAConnectByList dirancang untuk mendukung skenario kolaborasi peer-to-peer di mana aplikasi perlu terhubung ke simpul yang tersedia dari daftar simpul potensial. WSAConnectByList kompatibel dengan versi IPv6 dan IPv4.

Kumpulan kemungkinan tujuan, yang diwakili oleh daftar alamat, disediakan oleh pemanggil. WSAConnectByList melakukan lebih dari sekadar mencoba untuk terhubung ke salah satu dari mungkin banyak alamat tujuan. Secara khusus, fungsi ini mengambil semua alamat jarak jauh yang diteruskan oleh pemanggil, semua alamat lokal, dan kemudian mencoba koneksi terlebih dahulu menggunakan pasangan alamat dengan peluang keberhasilan tertinggi. Dengan demikian, WSAConnectByList tidak hanya memastikan bahwa koneksi akan dibuat jika koneksi sama sekali memungkinkan, tetapi juga meminimalkan waktu untuk membuat koneksi.

Pemanggil dapat menentukan buffer LocalAddress dan RemoteAddress dan panjang untuk menentukan alamat lokal dan jarak jauh yang koneksinya berhasil dibuat.

Parameter batas waktu memungkinkan pemanggil membatasi waktu yang dihabiskan oleh fungsi dalam membuat koneksi. Secara internal, WSAConnectByList melakukan beberapa operasi (upaya koneksi). Di antara setiap operasi, parameter batas waktu diperiksa untuk melihat apakah batas waktu telah terlampaui dan, jika demikian, panggilan dibatalkan. Perhatikan bahwa operasi individual (sambungkan) tidak akan terganggu setelah batas waktu terlampaui, sehingga panggilan WSAConnectByList dapat memakan waktu lebih lama untuk waktu habis daripada nilai yang ditentukan dalam parameter batas waktu .

WSAConnectByList memiliki batasan: Ini hanya berfungsi untuk soket berorientasi koneksi, seperti jenis SOCK_STREAM. Fungsi ini tidak mendukung perilaku I/O atau non-pemblokiran yang tumpang tindih. WSAConnectByList akan memblokir bahkan jika soket berada dalam mode non-pemblokiran. WSAConnectByList akan mencoba menyambungkan (satu per satu) ke berbagai alamat yang disediakan oleh pemanggil. Berpotensi, masing-masing upaya koneksi ini mungkin gagal dengan kode kesalahan yang berbeda. Karena hanya satu kode kesalahan yang dapat dikembalikan, nilai yang dikembalikan adalah kode kesalahan dari upaya koneksi terakhir.

Untuk mengaktifkan alamat IPv6 dan IPv4 untuk diteruskan dalam daftar alamat tunggal yang diterima oleh fungsi, langkah-langkah berikut harus dilakukan sebelum memanggil fungsi:

  • Fungsi setsockopt harus dipanggil pada soket yang dibuat untuk keluarga alamat AF_INET6 untuk menonaktifkan opsi soket IPV6_V6ONLY sebelum memanggil WSAConnectByList. Ini dicapai dengan memanggil fungsi setsockopt pada soket dengan parameter tingkat yang diatur ke IPPROTO_IPV6 (lihat IPPROTO_IPV6 Opsi Soket), parameter nama optname diatur ke IPV6_V6ONLY, dan nilai parameter optvalue diatur ke nol .
  • Alamat IPv4 apa pun harus diwakili dalam format alamat IPv6 yang dipetakan IPv4 yang memungkinkan aplikasi hanya IPv6 untuk berkomunikasi dengan simpul IPv4. Format alamat IPv6 yang dipetakan IPv4 memungkinkan alamat IPv4 dari simpul IPv4 diwakili sebagai alamat IPv6. Alamat IPv4 dikodekan ke dalam 32 bit berurutan rendah dari alamat IPv6, dan 96 bit pesanan tinggi menyimpan awalan tetap 0:0:0:0:0:FFFF. Format alamat IPv6 yang dipetakan IPv4 ditentukan dalam RFC 4291. Untuk informasi selengkapnya, lihat www.ietf.org/rfc/rfc4291.txt. Makro IN6ADDR_SETV4MAPPED dalam Mstcpip.h dapat digunakan untuk mengonversi alamat IPv4 ke format alamat IPv6 yang dipetakan IPv4 yang diperlukan.

Array pointer yang diteruskan dalam parameter SocketAddressList menunjuk ke array struktur SOCKET_ADDRESS , yang merupakan jenis data generik. Parameter RemoteAddress dan LocalAddress juga menunjuk ke struktur SOCKADDR . Ketika WSAConnectByList dipanggil, diharapkan bahwa jenis alamat soket khusus untuk protokol jaringan atau keluarga alamat yang digunakan akan benar-benar diteruskan dalam parameter ini. Jadi untuk alamat IPv4, pointer ke struktur sockaddr_in akan ditransmisikan ke pointer ke SOCKADDR ketika diteruskan sebagai parameter. Untuk alamat IPv6, pointer ke struktur sockaddr_in6 akan ditransmisikan ke pointer ke SOCKADDR saat diteruskan sebagai parameter. Parameter SocketAddressList dapat berisi pointer ke campuran alamat IPv4 dan IPv6. Jadi beberapa SOCKET_ADDRESS pointer bisa untuk sockaddr_in struktur dan yang lain bisa untuk sockaddr_in6 struktur. Jika diharapkan bahwa alamat IPv6 dapat digunakan, maka parameter RemoteAddress dan LocalAddress harus menunjuk ke struktur sockaddr_in6 dan ditransmisikan ke struktur SOCKADDR . Parameter RemoteAddressLength dan LocalAddressLength harus mewakili panjang struktur yang lebih besar ini.

Ketika fungsi WSAConnectByList mengembalikan TRUE, soket berada dalam status default untuk soket yang tersambung. Soket tidak mengaktifkan properti atau opsi yang diatur sebelumnya hingga SO_UPDATE_CONNECT_CONTEXT diatur pada soket. Gunakan fungsi setsockopt untuk mengatur opsi SO_UPDATE_CONNECT_CONTEXT.

Contohnya:

//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT

int iResult = 0;

iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );

Catatan Saat mengeluarkan panggilan Winsock pemblokiran seperti WSAConnectByList dengan parameter batas waktu diatur ke NULL, Winsock mungkin perlu menunggu peristiwa jaringan sebelum panggilan dapat selesai. Winsock melakukan penantian yang dapat diperingatkan dalam situasi ini, yang dapat terganggu oleh panggilan prosedur asinkron (APC) yang dijadwalkan pada utas yang sama. Mengeluarkan panggilan Winsock pemblokiran lain di dalam APC yang mengganggu panggilan Winsock pemblokiran yang sedang berlangsung pada utas yang sama akan menyebabkan perilaku yang tidak terdefinisi, dan tidak boleh dicoba oleh klien Winsock.
 
Windows Phone 8: Fungsi ini didukung untuk aplikasi Windows Phone Store di Windows Phone 8 dan yang lebih baru.

Windows 8.1 dan Windows Server 2012 R2: Fungsi ini didukung untuk aplikasi Windows Store di Windows 8.1, Windows Server 2012 R2, dan yang lebih baru.

Contoh

Buat koneksi menggunakan WSAConnectByList.

#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")


SOCKET
OpenAndConnect(SOCKET_ADDRESS_LIST *AddressList) 
{
    SOCKET ConnSocket = INVALID_SOCKET;

    int ipv6only = 0;
    int iResult;
    BOOL bSuccess;

    SOCKADDR_STORAGE LocalAddr = {0};
    SOCKADDR_STORAGE RemoteAddr = {0};

    DWORD dwLocalAddr = sizeof(LocalAddr);
    DWORD dwRemoteAddr = sizeof(RemoteAddr);

    ConnSocket = socket(AF_INET6, SOCK_STREAM, 0);
    if (ConnSocket == INVALID_SOCKET){
        return INVALID_SOCKET;
    }

    iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
        IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
    if (iResult == SOCKET_ERROR){
        closesocket(ConnSocket);
        return INVALID_SOCKET;       
    }

    // AddressList may contain IPv6 and/or IPv4Mapped addresses
    bSuccess = WSAConnectByList(ConnSocket,
            AddressList,
            &dwLocalAddr,
            (SOCKADDR*)&LocalAddr,
            &dwRemoteAddr,
            (SOCKADDR*)&RemoteAddr,
            NULL,
            NULL);
    if (bSuccess){
        return ConnSocket;
    } else {
        return INVALID_SOCKET;
    }
}

Persyaratan

   
Klien minimum yang didukung Windows 8.1, Windows Vista [aplikasi desktop | Aplikasi UWP]
Server minimum yang didukung Windows Server 2003 [aplikasi desktop | Aplikasi UWP]
Target Platform Windows
Header winsock2.h
Pustaka Ws2_32.lib
DLL Ws2_32.dll

Lihat juga

Opsi Soket IPPROTO_IPV6

SOCKADDR

SOCKET_ADDRESS

SOCKET_ADDRESS_LIST

WSAConnect

WSAConnectByName

WSAGetLastError

getaddrinfo

getpeername

getsockname

setsockopt