WSARecv
関数シグネチャ
// WS2_32.dll
#include <windows.h>
INT WSARecv(
SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd, // optional
DWORD* lpFlags,
OVERLAPPED* lpOverlapped, // optional
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| s | SOCKET | in | 接続済みソケットを識別するディスクリプタ。 |
| lpBuffers | WSABUF* | in | WSABUF 構造体の配列へのポインタ。各 WSABUF 構造体には、バッファへのポインタと、そのバッファの長さ(バイト単位)が格納されます。 |
| dwBufferCount | DWORD | in | lpBuffers 配列内の WSABUF 構造体の数。 |
| lpNumberOfBytesRecvd | DWORD* | outoptional | 受信操作がただちに完了した場合に、この呼び出しで受信したデータのバイト数を受け取るポインタ。 誤った結果を避けるため、lpOverlapped パラメーターが NULL でない場合は、このパラメーターに NULL を指定してください。このパラメーターを NULL にできるのは、lpOverlapped パラメーターが NULL でない場合のみです。 |
| lpFlags | DWORD* | inout | WSARecv 関数呼び出しの動作を変更するために使用するフラグへのポインタ。詳細については「解説」のセクションを参照してください。 |
| lpOverlapped | OVERLAPPED* | inoutoptional | WSAOVERLAPPED 構造体へのポインタ(非オーバーラップソケットでは無視されます)。 |
| lpCompletionRoutine | LPWSAOVERLAPPED_COMPLETION_ROUTINE | inoptional | 受信操作が完了したときに呼び出される完了ルーチンへのポインタ(非オーバーラップソケットでは無視されます)。 |
戻り値の型: INT
公式ドキュメント
接続済みソケット、またはバインド済みのコネクションレスソケットからデータを受信します。(WSARecv)
戻り値
エラーが発生せず、受信操作がただちに完了した場合、 WSARecv はゼロを返します。この場合、呼び出し側スレッドがアラート可能状態(alertable state)になった時点で完了ルーチンが呼び出されるよう、すでにスケジュールされています。それ以外の場合は SOCKET_ERROR が返され、 WSAGetLastError を呼び出すことで具体的なエラーコードを取得できます。エラーコード WSA_IO_PENDING は、オーバーラップ操作が正常に開始され、完了は後で通知されることを示します。それ以外のエラーコードは、オーバーラップ操作が正常に開始されず、完了通知が発生しないことを示します。
| エラーコード | 意味 |
|---|---|
| タイムアウトまたはその他の障害により、仮想回線が終了しました。 | |
| ストリームソケットの場合、リモート側によって仮想回線がリセットされました。このソケットは使用できなくなるため、アプリケーションはソケットを閉じる必要があります。UDP データグラムソケットの場合、このエラーは、以前の送信操作によって ICMP の「Port Unreachable(ポート到達不能)」メッセージが返されたことを示します。 | |
| ソケット s はメッセージ指向であり、仮想回線がリモート側によって正常に閉じられました。 | |
| lpBuffers パラメーターが、ユーザーアドレス空間の有効な部分に完全には収まっていません。 | |
| ブロッキングを伴う Windows Sockets 1.1 の呼び出しが進行中であるか、サービスプロバイダーがコールバック関数を処理中です。 | |
| (ブロッキングを伴う)呼び出しが WSACancelBlockingCall 関数によってキャンセルされました。 | |
| ソケットが(たとえば bind で)バインドされていません。 | |
| メッセージが大きすぎて指定されたバッファに収まらず、(信頼性のないプロトコルの場合のみ)バッファに収まらなかったメッセージの末尾部分は破棄されました。 | |
| ネットワークサブシステムに障害が発生しました。 | |
| コネクション指向ソケットの場合、このエラーは、操作の進行中に障害を検出した keep-alive 動作によって接続が切断されたことを示します。データグラムソケットの場合、このエラーは存続時間(time to live)が経過したことを示します。 | |
| ソケットが接続されていません。 | |
| ディスクリプタがソケットではありません。 | |
| MSG_OOB が指定されましたが、ソケットが SOCK_STREAM 型のようなストリーム形式ではない、OOB データがこのソケットに関連付けられた通信ドメインでサポートされていない、またはソケットが単方向で送信操作のみをサポートしています。 | |
| ソケットがシャットダウンされています。how に SD_RECEIVE または SD_BOTH を指定して shutdown を呼び出した後は、そのソケットに対して WSARecv を呼び出すことはできません。 | |
| ネットワーク障害が発生したか、ピアシステムが応答しなかったため、接続が切断されました。 | |
|
Windows NT: オーバーラップソケットの場合: 未完了のオーバーラップ I/O 要求が多すぎます。非オーバーラップソケットの場合: ソケットが非ブロッキングとしてマークされており、受信操作をただちに完了できません。 |
|
| この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。 | |
| オーバーラップ操作が正常に開始され、完了は後で通知されます。 | |
| ソケットが閉じられたため、オーバーラップ操作がキャンセルされました。 |
解説(Remarks)
WSARecv 関数は、標準の recv 関数と比べて、次の 3 つの重要な点で追加機能を提供します。
- オーバーラップソケットと組み合わせて、オーバーラップ recv 操作を実行できます。
- 複数の受信バッファを指定できるため、スキャッター/ギャザー型の I/O に適用できます。
- lpFlags パラメーターは入力時と出力時の両方で使用されるため、アプリケーションは MSG_PARTIAL フラグビットの出力状態を検知できます。ただし、MSG_PARTIAL フラグビットはすべてのプロトコルでサポートされているわけではありません。
WSARecv 関数は、s パラメーターで指定された接続済みソケットまたはバインド済みのコネクションレスソケットに対して使用し、受信データを読み取るために使用します。ソケットのローカルアドレスが既知である必要があります。サーバーアプリケーションでは、通常これは bind によって明示的に行うか、 accept または WSAAccept によって暗黙的に行われます。クライアントアプリケーションでは明示的なバインドは推奨されません。クライアントアプリケーションでは、 connect、 WSAConnect、 sendto、 WSASendTo、または WSAJoinLeaf を通じて、ソケットがローカルアドレスに暗黙的にバインドされます。
接続済みのコネクションレスソケットの場合、この関数は受信メッセージを受け付けるアドレスを制限します。接続で指定されたリモートアドレスからのメッセージのみを返します。他のアドレスからのメッセージは(暗黙のうちに)破棄されます。
オーバーラップソケットの場合、 WSARecv は、受信データが利用可能になり次第格納するための 1 つ以上のバッファを投入するために使用され、その後、アプリケーションが指定した完了通知(完了ルーチンの呼び出しまたはイベントオブジェクトのシグナル状態への設定)が発生します。操作がただちに完了しない場合、最終的な完了状態は完了ルーチンまたは WSAGetOverlappedResult を通じて取得します。
非オーバーラップソケットの場合、ブロッキングのセマンティクスは標準の recv 関数と同一であり、lpOverlapped および lpCompletionRoutine パラメーターは無視されます。トランスポートによってすでに受信・バッファリングされているデータは、指定されたユーザーバッファにコピーされます。ブロッキングソケットで、トランスポートによって現在受信・バッファリングされているデータがない場合、呼び出しはデータが受信されるまでブロックします。Windows Sockets 2 は、この関数に対する標準的なブロッキングタイムアウト機構を定義していません。バイトストリームプロトコルとして動作するプロトコルの場合、スタックは利用可能なバッファ領域と受信済みデータ量に応じて、可能な限り多くのデータを返そうとします。ただし、1 バイトでも受信すれば呼び出し側のブロックを解除するのに十分です。1 バイトを超えるデータが返される保証はありません。メッセージ指向として動作するプロトコルの場合、呼び出し側のブロックを解除するには完全なメッセージが必要です。
| XP1_MESSAGE_ORIENTED | XP1_PSEUDO_STREAM | MSG_PARTIAL | 動作 |
|---|---|---|---|
| 未設定 | * | * | バイトストリーム |
| * | 設定 | * | バイトストリーム |
| 設定 | 未設定 | 設定 | バイトストリーム |
| 設定 | 未設定 | 未設定 | メッセージ指向 |
バッファは、lpBuffers が指す配列に現れる順序で埋められ、間に隙間が生じないように詰めて格納されます。
この関数がオーバーラップ方式で完了する場合、この呼び出しから戻る前に WSABUF 構造体を取り込むのは Winsock サービスプロバイダーの責任です。これにより、アプリケーションは lpBuffers パラメーターが指すスタックベースの WSABUF 配列を構築できます。
バイトストリーム形式のソケット(たとえば SOCK_STREAM 型)の場合、受信データは、バッファが満たされるか、接続が閉じられるか、内部でバッファリングされたデータがなくなるまで、バッファに格納されます。受信データがすべてのバッファを満たすかどうかにかかわらず、オーバーラップソケットでは完了通知が発生します。
メッセージ指向ソケット(たとえば SOCK_DGRAM 型)の場合、受信メッセージはバッファの合計サイズまでバッファに格納され、オーバーラップソケットでは完了通知が発生します。メッセージがバッファより大きい場合、バッファにはメッセージの先頭部分が格納されます。基盤となるサービスプロバイダーが MSG_PARTIAL 機能をサポートしている場合、lpFlags に MSG_PARTIAL フラグが設定され、後続の受信操作でメッセージの残りが取得されます。MSG_PARTIAL がサポートされていないがプロトコルが信頼性のあるものである場合、 WSARecv はエラー WSAEMSGSIZE を生成し、より大きなバッファを指定した後続の受信操作でメッセージ全体を取得できます。それ以外の場合(つまり、プロトコルが信頼性がなく MSG_PARTIAL をサポートしていない場合)、超過分のデータは失われ、 WSARecv はエラー WSAEMSGSIZE を生成します。
コネクション指向ソケットの場合、 WSARecv は、ソケットがバイトストリームかメッセージ指向かに応じて、2 つの方法のいずれかで仮想回線の正常終了を通知できます。バイトストリームの場合、0 バイトが読み取られたこと(成功を示すゼロの戻り値と、lpNumberOfBytesRecvd の値がゼロであることで示されます)が、正常終了とそれ以上バイトが読み取られないことを示します。0 バイトメッセージがしばしば許容されるメッセージ指向ソケットの場合、エラーコード WSAEDISCON による失敗が正常終了を示すために使用されます。いずれの場合も、戻りエラーコード WSAECONNRESET は、強制的なクローズが発生したことを示します。
lpFlags パラメーターは、関連付けられたソケットに対して指定されたオプションを超えて、関数呼び出しの動作に影響を与えるために使用できます。つまり、この関数のセマンティクスは、ソケットオプションと lpFlags パラメーターによって決まります。後者は、次の表に示す値のいずれかをビット単位の OR 演算子で組み合わせて構築します。
| 値 | 意味 |
|---|---|
| MSG_PEEK |
受信データを覗き見します。データはバッファにコピーされますが、入力キューからは削除されません。
このフラグは非オーバーラップソケットでのみ有効です。 |
| MSG_OOB | OOB データを処理します。 |
| MSG_PARTIAL |
このフラグはメッセージ指向ソケット専用です。出力時には、このフラグは指定されたデータが送信側によって送信されたメッセージの一部であることを示します。メッセージの残りの部分は後続の受信操作で指定されます。MSG_PARTIAL フラグがクリアされた後続の受信操作は、送信側メッセージの終端を示します。
入力パラメーターとして、このフラグは、トランスポートプロバイダーがメッセージの一部のみを受信した場合でも受信操作を完了すべきであることを示します。 |
| MSG_PUSH_IMMEDIATE |
このフラグはストリーム指向ソケット専用です。このフラグにより、ストリームソケットを使用するアプリケーションは、部分的に満たされた保留中の受信要求の完了を遅延させないようトランスポートプロバイダーに指示できます。これは、まだ転送中の可能性のある残りのデータを必ずしも待たずに、できるだけ早く受信データを受け取りたいというアプリケーションの意図をトランスポートプロバイダーに伝えるヒントです。何をもって部分的に満たされた保留中の受信要求とみなすかは、トランスポート固有の事項です。
TCP の場合、これは、受信した TCP セグメントが受信要求のデータバッファに格納されており、どの TCP セグメントも PUSH ビットの値が 1 を示していなかった場合を指します。この場合、TCP は、PUSH ビットが 1 に設定された TCP セグメントとともに残りのデータが到着するのを待つために、部分的に満たされた受信要求をもう少し長く保持することがあります。このフラグは、受信要求を保持せずただちに完了するよう TCP に指示します。 部分ブロックの処理は最適でないことが多いため、大きなブロック転送にこのフラグを使用することは推奨されません。このフラグは、部分データをただちに受信・処理することが処理レイテンシの低減に役立つ場合にのみ有用です。 このフラグは実際の保証ではなくヒントです。 このフラグは Windows 8.1、Windows Server 2012 R2 以降でサポートされています。 |
| MSG_WAITALL |
受信要求は、次のいずれかのイベントが発生した場合にのみ完了します。
基盤となるトランスポートプロバイダーが MSG_WAITALL をサポートしていない場合、またはソケットが非ブロッキングモードである場合、この呼び出しは WSAEOPNOTSUPP で失敗することに注意してください。また、MSG_WAITALL が MSG_OOB、MSG_PEEK、または MSG_PARTIAL とともに指定された場合も、この呼び出しは WSAEOPNOTSUPP で失敗します。 このフラグはデータグラムソケットおよびメッセージ指向ソケットではサポートされていません。 |
メッセージ指向ソケットの場合、部分メッセージを受信すると lpFlags パラメーターに MSG_PARTIAL ビットが設定されます。完全なメッセージを受信すると、lpFlags の MSG_PARTIAL はクリアされます。完了が遅延する場合、lpFlags が指す値は更新されません。完了が通知されたら、アプリケーションは WSAGetOverlappedResult を呼び出し、lpdwFlags パラメーターで示されるフラグを確認する必要があります。
オーバーラップソケット I/O
オーバーラップ操作がただちに完了した場合、 WSARecv はゼロを返し、lpNumberOfBytesRecvd パラメーターは受信したバイト数で更新され、lpFlags パラメーターで示されるフラグビットも更新されます。オーバーラップ操作が正常に開始され後で完了する場合、 WSARecv は SOCKET_ERROR を返し、エラーコード WSA_IO_PENDING を示します。この場合、lpNumberOfBytesRecvd と lpFlags は更新されません。オーバーラップ操作が完了すると、転送されたデータ量は、完了ルーチンの cbTransferred パラメーター(指定されている場合)を通じて、または WSAGetOverlappedResult の lpcbTransfer パラメーターを通じて示されます。フラグ値は WSAGetOverlappedResult の lpdwFlags パラメーターを調べることで取得されます。オーバーラップ I/O を使用する WSARecv 関数は、直前の WSARecv、 WSARecvFrom、 WSASend、または WSASendTo 関数の完了ルーチン内から呼び出すことができます。所定のソケットについて、I/O 完了ルーチンが入れ子になることはありません。これにより、時間に敏感なデータ送信を、完全にプリエンプティブなコンテキスト内で行うことができます。
lpOverlapped パラメーターは、オーバーラップ操作の継続中、有効である必要があります。複数の I/O 操作が同時に未完了である場合、それぞれが別個の WSAOVERLAPPED 構造体を参照する必要があります。
lpCompletionRoutine パラメーターが NULL の場合、lpOverlapped の hEvent パラメーターが有効なイベントオブジェクトハンドルを含んでいれば、オーバーラップ操作の完了時にそれがシグナル状態になります。アプリケーションは WSAWaitForMultipleEvents または WSAGetOverlappedResult を使用して、イベントオブジェクトを待機またはポーリングできます。
lpCompletionRoutine が NULL でない場合、hEvent パラメーターは無視され、アプリケーションが完了ルーチンにコンテキスト情報を渡すために使用できます。NULL でない lpCompletionRoutine を渡し、後で同じオーバーラップ I/O 要求に対して WSAGetOverlappedResult を呼び出す場合、その WSAGetOverlappedResult 呼び出しで fWait パラメーターを TRUE に設定してはなりません。この場合、hEvent パラメーターの使用は未定義であり、hEvent パラメーターを待機しようとすると予測不能な結果が生じます。
完了ルーチンは、Windows のファイル I/O 完了ルーチンに規定されているのと同じ規則に従います。完了ルーチンは、fAlertable パラメーターを TRUE に設定して WSAWaitForMultipleEvents 関数が呼び出された場合などに発生する、スレッドがアラート可能な待機状態になるまで呼び出されません。
完了ルーチンのプロトタイプは次のとおりです。
void CALLBACK CompletionROUTINE(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine は、アプリケーション定義またはライブラリ定義の関数名のプレースホルダーです。dwError は、lpOverlapped で示されるオーバーラップ操作の完了状態を指定します。cbTransferred パラメーターは、受信したバイト数を指定します。dwFlags パラメーターには、受信操作がただちに完了していた場合に lpFlags に現れたであろう情報が含まれます。この関数は値を返しません。
この関数から戻ると、このソケットに対する別の保留中の完了ルーチンを呼び出すことができます。 WSAWaitForMultipleEvents を使用する場合、待機中のすべての完了ルーチンは、アラート可能なスレッドの待機が戻りコード WSA_IO_COMPLETION で満たされる前に呼び出されます。完了ルーチンは任意の順序で呼び出される可能性があり、必ずしもオーバーラップ操作が完了した順序と同じとは限りません。ただし、投入されたバッファは、指定された順序と同じ順序で埋められることが保証されます。
I/O 完了ポートを使用する場合、WSARecv を呼び出した順序がバッファに格納される順序でもあることに注意してください。予測不能なバッファ順序になる可能性があるため、WSARecv を異なるスレッドから同じソケットに対して同時に呼び出してはなりません。
サンプルコード
次の例は、オーバーラップ I/O モードで WSARecv 関数を使用する方法を示しています。#ifndef UNICODE
#define UNICODE
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable: 4127) // Conditional expression is a constant
#define DATA_BUFSIZE 4096
int __cdecl main(int argc, char **argv)
{
WSADATA wsd;
struct addrinfo *result = NULL, *ptr = NULL, hints;
WSAOVERLAPPED RecvOverlapped;
SOCKET ConnSocket = INVALID_SOCKET;
WSABUF DataBuf;
DWORD RecvBytes, Flags;
char buffer[DATA_BUFSIZE];
int err = 0;
int rc;
if (argc != 2) {
wprintf(L"usage: %s server-name\n", argv[0]);
return 1;
}
// Load Winsock
rc = WSAStartup(MAKEWORD(2, 2), &wsd);
if (rc != 0) {
wprintf(L"Unable to load Winsock: %d\n", rc);
return 1;
}
// Make sure the hints struct is zeroed out
SecureZeroMemory((PVOID) & hints, sizeof (struct addrinfo));
// Initialize the hints to retrieve the server address for IPv4
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
rc = getaddrinfo(argv[1], "27015", &hints, &result);
if (rc != 0) {
wprintf(L"getaddrinfo failed with error: %d\n", rc);
return 1;
}
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
ConnSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
return 1;
}
rc = connect(ConnSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
if (rc == SOCKET_ERROR) {
if (WSAECONNREFUSED == (err = WSAGetLastError())) {
closesocket(ConnSocket);
ConnSocket = INVALID_SOCKET;
continue;
}
wprintf(L"connect failed with error: %d\n", err);
freeaddrinfo(result);
closesocket(ConnSocket);
return 1;
}
break;
}
if (ConnSocket == INVALID_SOCKET) {
wprintf(L"Unable to establish connection with the server!\n");
freeaddrinfo(result);
return 1;
}
wprintf(L"Client connected...\n");
// Make sure the RecvOverlapped struct is zeroed out
SecureZeroMemory((PVOID) & RecvOverlapped, sizeof (WSAOVERLAPPED));
// Create an event handle and setup an overlapped structure.
RecvOverlapped.hEvent = WSACreateEvent();
if (RecvOverlapped.hEvent == NULL) {
wprintf(L"WSACreateEvent failed: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ConnSocket);
return 1;
}
DataBuf.len = DATA_BUFSIZE;
DataBuf.buf = buffer;
// Call WSARecv until the peer closes the connection
// or until an error occurs
while (1) {
Flags = 0;
rc = WSARecv(ConnSocket, &DataBuf, 1, &RecvBytes, &Flags, &RecvOverlapped, NULL);
if ((rc == SOCKET_ERROR) && (WSA_IO_PENDING != (err = WSAGetLastError()))) {
wprintf(L"WSARecv failed with error: %d\n", err);
break;
}
rc = WSAWaitForMultipleEvents(1, &RecvOverlapped.hEvent, TRUE, INFINITE, TRUE);
if (rc == WSA_WAIT_FAILED) {
wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
break;
}
rc = WSAGetOverlappedResult(ConnSocket, &RecvOverlapped, &RecvBytes, FALSE, &Flags);
if (rc == FALSE) {
wprintf(L"WSARecv operation failed with error: %d\n", WSAGetLastError());
break;
}
wprintf(L"Read %d bytes\n", RecvBytes);
WSAResetEvent(RecvOverlapped.hEvent);
// If 0 bytes are received, the connection was closed
if (RecvBytes == 0)
break;
}
WSACloseEvent(RecvOverlapped.hEvent);
closesocket(ConnSocket);
freeaddrinfo(result);
WSACleanup();
return 0;
}
Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストアアプリでサポートされています。
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
INT WSARecv(
SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd, // optional
DWORD* lpFlags,
OVERLAPPED* lpOverlapped, // optional
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // optional
);[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSARecv(
UIntPtr s, // SOCKET
IntPtr lpBuffers, // WSABUF*
uint dwBufferCount, // DWORD
IntPtr lpNumberOfBytesRecvd, // DWORD* optional, out
ref uint lpFlags, // DWORD* in/out
IntPtr lpOverlapped, // OVERLAPPED* optional, in/out
IntPtr lpCompletionRoutine // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
);<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSARecv(
s As UIntPtr, ' SOCKET
lpBuffers As IntPtr, ' WSABUF*
dwBufferCount As UInteger, ' DWORD
lpNumberOfBytesRecvd As IntPtr, ' DWORD* optional, out
ByRef lpFlags As UInteger, ' DWORD* in/out
lpOverlapped As IntPtr, ' OVERLAPPED* optional, in/out
lpCompletionRoutine As IntPtr ' LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
) As Integer
End Function' s : SOCKET
' lpBuffers : WSABUF*
' dwBufferCount : DWORD
' lpNumberOfBytesRecvd : DWORD* optional, out
' lpFlags : DWORD* in/out
' lpOverlapped : OVERLAPPED* optional, in/out
' lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
Declare PtrSafe Function WSARecv Lib "ws2_32" ( _
ByVal s As LongPtr, _
ByVal lpBuffers As LongPtr, _
ByVal dwBufferCount As Long, _
ByVal lpNumberOfBytesRecvd As LongPtr, _
ByRef lpFlags As Long, _
ByVal lpOverlapped As LongPtr, _
ByVal lpCompletionRoutine As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
WSARecv = ctypes.windll.ws2_32.WSARecv
WSARecv.restype = ctypes.c_int
WSARecv.argtypes = [
ctypes.c_size_t, # s : SOCKET
ctypes.c_void_p, # lpBuffers : WSABUF*
wintypes.DWORD, # dwBufferCount : DWORD
ctypes.POINTER(wintypes.DWORD), # lpNumberOfBytesRecvd : DWORD* optional, out
ctypes.POINTER(wintypes.DWORD), # lpFlags : DWORD* in/out
ctypes.c_void_p, # lpOverlapped : OVERLAPPED* optional, in/out
ctypes.c_void_p, # lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('WS2_32.dll')
WSARecv = Fiddle::Function.new(
lib['WSARecv'],
[
Fiddle::TYPE_UINTPTR_T, # s : SOCKET
Fiddle::TYPE_VOIDP, # lpBuffers : WSABUF*
-Fiddle::TYPE_INT, # dwBufferCount : DWORD
Fiddle::TYPE_VOIDP, # lpNumberOfBytesRecvd : DWORD* optional, out
Fiddle::TYPE_VOIDP, # lpFlags : DWORD* in/out
Fiddle::TYPE_VOIDP, # lpOverlapped : OVERLAPPED* optional, in/out
Fiddle::TYPE_VOIDP, # lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
],
Fiddle::TYPE_INT)#[link(name = "ws2_32")]
extern "system" {
fn WSARecv(
s: usize, // SOCKET
lpBuffers: *mut WSABUF, // WSABUF*
dwBufferCount: u32, // DWORD
lpNumberOfBytesRecvd: *mut u32, // DWORD* optional, out
lpFlags: *mut u32, // DWORD* in/out
lpOverlapped: *mut OVERLAPPED, // OVERLAPPED* optional, in/out
lpCompletionRoutine: *const core::ffi::c_void // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSARecv(UIntPtr s, IntPtr lpBuffers, uint dwBufferCount, IntPtr lpNumberOfBytesRecvd, ref uint lpFlags, IntPtr lpOverlapped, IntPtr lpCompletionRoutine);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSARecv' -Namespace Win32 -PassThru
# $api::WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)#uselib "WS2_32.dll"
#func global WSARecv "WSARecv" sptr, sptr, sptr, sptr, sptr, sptr, sptr
; WSARecv s, varptr(lpBuffers), dwBufferCount, varptr(lpNumberOfBytesRecvd), varptr(lpFlags), varptr(lpOverlapped), lpCompletionRoutine ; 戻り値は stat
; s : SOCKET -> "sptr"
; lpBuffers : WSABUF* -> "sptr"
; dwBufferCount : DWORD -> "sptr"
; lpNumberOfBytesRecvd : DWORD* optional, out -> "sptr"
; lpFlags : DWORD* in/out -> "sptr"
; lpOverlapped : OVERLAPPED* optional, in/out -> "sptr"
; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSARecv "WSARecv" sptr, var, int, var, var, var, sptr ; res = WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine) ; s : SOCKET -> "sptr" ; lpBuffers : WSABUF* -> "var" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "var" ; lpFlags : DWORD* in/out -> "var" ; lpOverlapped : OVERLAPPED* optional, in/out -> "var" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "sptr" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSARecv "WSARecv" sptr, sptr, int, sptr, sptr, sptr, sptr ; res = WSARecv(s, varptr(lpBuffers), dwBufferCount, varptr(lpNumberOfBytesRecvd), varptr(lpFlags), varptr(lpOverlapped), lpCompletionRoutine) ; s : SOCKET -> "sptr" ; lpBuffers : WSABUF* -> "sptr" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "sptr" ; lpFlags : DWORD* in/out -> "sptr" ; lpOverlapped : OVERLAPPED* optional, in/out -> "sptr" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; INT WSARecv(SOCKET s, WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesRecvd, DWORD* lpFlags, OVERLAPPED* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) #uselib "WS2_32.dll" #cfunc global WSARecv "WSARecv" intptr, var, int, var, var, var, intptr ; res = WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine) ; s : SOCKET -> "intptr" ; lpBuffers : WSABUF* -> "var" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "var" ; lpFlags : DWORD* in/out -> "var" ; lpOverlapped : OVERLAPPED* optional, in/out -> "var" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "intptr" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; INT WSARecv(SOCKET s, WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesRecvd, DWORD* lpFlags, OVERLAPPED* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) #uselib "WS2_32.dll" #cfunc global WSARecv "WSARecv" intptr, intptr, int, intptr, intptr, intptr, intptr ; res = WSARecv(s, varptr(lpBuffers), dwBufferCount, varptr(lpNumberOfBytesRecvd), varptr(lpFlags), varptr(lpOverlapped), lpCompletionRoutine) ; s : SOCKET -> "intptr" ; lpBuffers : WSABUF* -> "intptr" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "intptr" ; lpFlags : DWORD* in/out -> "intptr" ; lpOverlapped : OVERLAPPED* optional, in/out -> "intptr" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSARecv = ws2_32.NewProc("WSARecv")
)
// s (SOCKET), lpBuffers (WSABUF*), dwBufferCount (DWORD), lpNumberOfBytesRecvd (DWORD* optional, out), lpFlags (DWORD* in/out), lpOverlapped (OVERLAPPED* optional, in/out), lpCompletionRoutine (LPWSAOVERLAPPED_COMPLETION_ROUTINE optional)
r1, _, err := procWSARecv.Call(
uintptr(s),
uintptr(lpBuffers),
uintptr(dwBufferCount),
uintptr(lpNumberOfBytesRecvd),
uintptr(lpFlags),
uintptr(lpOverlapped),
uintptr(lpCompletionRoutine),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // INTfunction WSARecv(
s: NativeUInt; // SOCKET
lpBuffers: Pointer; // WSABUF*
dwBufferCount: DWORD; // DWORD
lpNumberOfBytesRecvd: Pointer; // DWORD* optional, out
lpFlags: Pointer; // DWORD* in/out
lpOverlapped: Pointer; // OVERLAPPED* optional, in/out
lpCompletionRoutine: Pointer // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): Integer; stdcall;
external 'WS2_32.dll' name 'WSARecv';result := DllCall("WS2_32\WSARecv"
, "UPtr", s ; SOCKET
, "Ptr", lpBuffers ; WSABUF*
, "UInt", dwBufferCount ; DWORD
, "Ptr", lpNumberOfBytesRecvd ; DWORD* optional, out
, "Ptr", lpFlags ; DWORD* in/out
, "Ptr", lpOverlapped ; OVERLAPPED* optional, in/out
, "Ptr", lpCompletionRoutine ; LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
, "Int") ; return: INT●WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine) = DLL("WS2_32.dll", "int WSARecv(int, void*, dword, void*, void*, void*, void*)")
# 呼び出し: WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)
# s : SOCKET -> "int"
# lpBuffers : WSABUF* -> "void*"
# dwBufferCount : DWORD -> "dword"
# lpNumberOfBytesRecvd : DWORD* optional, out -> "void*"
# lpFlags : DWORD* in/out -> "void*"
# lpOverlapped : OVERLAPPED* optional, in/out -> "void*"
# lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "ws2_32" fn WSARecv(
s: usize, // SOCKET
lpBuffers: [*c]WSABUF, // WSABUF*
dwBufferCount: u32, // DWORD
lpNumberOfBytesRecvd: [*c]u32, // DWORD* optional, out
lpFlags: [*c]u32, // DWORD* in/out
lpOverlapped: [*c]OVERLAPPED, // OVERLAPPED* optional, in/out
lpCompletionRoutine: ?*anyopaque // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
) callconv(std.os.windows.WINAPI) i32;proc WSARecv(
s: uint, # SOCKET
lpBuffers: ptr WSABUF, # WSABUF*
dwBufferCount: uint32, # DWORD
lpNumberOfBytesRecvd: ptr uint32, # DWORD* optional, out
lpFlags: ptr uint32, # DWORD* in/out
lpOverlapped: ptr OVERLAPPED, # OVERLAPPED* optional, in/out
lpCompletionRoutine: pointer # LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): int32 {.importc: "WSARecv", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int WSARecv(
size_t s, // SOCKET
WSABUF* lpBuffers, // WSABUF*
uint dwBufferCount, // DWORD
uint* lpNumberOfBytesRecvd, // DWORD* optional, out
uint* lpFlags, // DWORD* in/out
OVERLAPPED* lpOverlapped, // OVERLAPPED* optional, in/out
void* lpCompletionRoutine // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
);ccall((:WSARecv, "WS2_32.dll"), stdcall, Int32,
(Csize_t, Ptr{WSABUF}, UInt32, Ptr{UInt32}, Ptr{UInt32}, Ptr{OVERLAPPED}, Ptr{Cvoid}),
s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)
# s : SOCKET -> Csize_t
# lpBuffers : WSABUF* -> Ptr{WSABUF}
# dwBufferCount : DWORD -> UInt32
# lpNumberOfBytesRecvd : DWORD* optional, out -> Ptr{UInt32}
# lpFlags : DWORD* in/out -> Ptr{UInt32}
# lpOverlapped : OVERLAPPED* optional, in/out -> Ptr{OVERLAPPED}
# lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Ptr{Cvoid}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t WSARecv(
uintptr_t s,
void* lpBuffers,
uint32_t dwBufferCount,
uint32_t* lpNumberOfBytesRecvd,
uint32_t* lpFlags,
void* lpOverlapped,
void* lpCompletionRoutine);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)
-- s : SOCKET
-- lpBuffers : WSABUF*
-- dwBufferCount : DWORD
-- lpNumberOfBytesRecvd : DWORD* optional, out
-- lpFlags : DWORD* in/out
-- lpOverlapped : OVERLAPPED* optional, in/out
-- lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSARecv = lib.func('__stdcall', 'WSARecv', 'int32_t', ['uintptr_t', 'void *', 'uint32_t', 'uint32_t *', 'uint32_t *', 'void *', 'void *']);
// WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)
// s : SOCKET -> 'uintptr_t'
// lpBuffers : WSABUF* -> 'void *'
// dwBufferCount : DWORD -> 'uint32_t'
// lpNumberOfBytesRecvd : DWORD* optional, out -> 'uint32_t *'
// lpFlags : DWORD* in/out -> 'uint32_t *'
// lpOverlapped : OVERLAPPED* optional, in/out -> 'void *'
// lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
// コールバック(関数ポインタ)は koffi.proto/koffi.register で型を定義して渡す(素の void* では JS 関数を渡せない)。const lib = Deno.dlopen("WS2_32.dll", {
WSARecv: { parameters: ["usize", "pointer", "u32", "pointer", "pointer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)
// s : SOCKET -> "usize"
// lpBuffers : WSABUF* -> "pointer"
// dwBufferCount : DWORD -> "u32"
// lpNumberOfBytesRecvd : DWORD* optional, out -> "pointer"
// lpFlags : DWORD* in/out -> "pointer"
// lpOverlapped : OVERLAPPED* optional, in/out -> "pointer"
// lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t WSARecv(
size_t s,
void* lpBuffers,
uint32_t dwBufferCount,
uint32_t* lpNumberOfBytesRecvd,
uint32_t* lpFlags,
void* lpOverlapped,
void* lpCompletionRoutine);
C, "WS2_32.dll");
// $ffi->WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
// s : SOCKET
// lpBuffers : WSABUF*
// dwBufferCount : DWORD
// lpNumberOfBytesRecvd : DWORD* optional, out
// lpFlags : DWORD* in/out
// lpOverlapped : OVERLAPPED* optional, in/out
// lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public interface Ws2_32 extends StdCallLibrary {
Ws2_32 INSTANCE = Native.load("ws2_32", Ws2_32.class);
int WSARecv(
long s, // SOCKET
Pointer lpBuffers, // WSABUF*
int dwBufferCount, // DWORD
IntByReference lpNumberOfBytesRecvd, // DWORD* optional, out
IntByReference lpFlags, // DWORD* in/out
Pointer lpOverlapped, // OVERLAPPED* optional, in/out
Callback lpCompletionRoutine // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
);
}@[Link("ws2_32")]
lib LibWS2_32
fun WSARecv = WSARecv(
s : LibC::SizeT, # SOCKET
lpBuffers : WSABUF*, # WSABUF*
dwBufferCount : UInt32, # DWORD
lpNumberOfBytesRecvd : UInt32*, # DWORD* optional, out
lpFlags : UInt32*, # DWORD* in/out
lpOverlapped : OVERLAPPED*, # OVERLAPPED* optional, in/out
lpCompletionRoutine : Void* # LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef WSARecvNative = Int32 Function(UintPtr, Pointer<Void>, Uint32, Pointer<Uint32>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>);
typedef WSARecvDart = int Function(int, Pointer<Void>, int, Pointer<Uint32>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>);
final WSARecv = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSARecvNative, WSARecvDart>('WSARecv');
// s : SOCKET -> UintPtr
// lpBuffers : WSABUF* -> Pointer<Void>
// dwBufferCount : DWORD -> Uint32
// lpNumberOfBytesRecvd : DWORD* optional, out -> Pointer<Uint32>
// lpFlags : DWORD* in/out -> Pointer<Uint32>
// lpOverlapped : OVERLAPPED* optional, in/out -> Pointer<Void>
// lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSARecv(
s: NativeUInt; // SOCKET
lpBuffers: Pointer; // WSABUF*
dwBufferCount: DWORD; // DWORD
lpNumberOfBytesRecvd: Pointer; // DWORD* optional, out
lpFlags: Pointer; // DWORD* in/out
lpOverlapped: Pointer; // OVERLAPPED* optional, in/out
lpCompletionRoutine: Pointer // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): Integer; stdcall;
external 'WS2_32.dll' name 'WSARecv';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSARecv"
c_WSARecv :: CUIntPtr -> Ptr () -> Word32 -> Ptr Word32 -> Ptr Word32 -> Ptr () -> Ptr () -> IO Int32
-- s : SOCKET -> CUIntPtr
-- lpBuffers : WSABUF* -> Ptr ()
-- dwBufferCount : DWORD -> Word32
-- lpNumberOfBytesRecvd : DWORD* optional, out -> Ptr Word32
-- lpFlags : DWORD* in/out -> Ptr Word32
-- lpOverlapped : OVERLAPPED* optional, in/out -> Ptr ()
-- lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsarecv =
foreign "WSARecv"
(size_t @-> (ptr void) @-> uint32_t @-> (ptr uint32_t) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* lpBuffers : WSABUF* -> (ptr void) *)
(* dwBufferCount : DWORD -> uint32_t *)
(* lpNumberOfBytesRecvd : DWORD* optional, out -> (ptr uint32_t) *)
(* lpFlags : DWORD* in/out -> (ptr uint32_t) *)
(* lpOverlapped : OVERLAPPED* optional, in/out -> (ptr void) *)
(* lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library ws2_32 (t "WS2_32.dll"))
(cffi:use-foreign-library ws2_32)
(cffi:defcfun ("WSARecv" wsarecv :convention :stdcall) :int32
(s :uint64) ; SOCKET
(lp-buffers :pointer) ; WSABUF*
(dw-buffer-count :uint32) ; DWORD
(lp-number-of-bytes-recvd :pointer) ; DWORD* optional, out
(lp-flags :pointer) ; DWORD* in/out
(lp-overlapped :pointer) ; OVERLAPPED* optional, in/out
(lp-completion-routine :pointer)) ; LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $WSARecv = Win32::API::More->new('WS2_32',
'int WSARecv(WPARAM s, LPVOID lpBuffers, DWORD dwBufferCount, LPVOID lpNumberOfBytesRecvd, LPVOID lpFlags, LPVOID lpOverlapped, LPVOID lpCompletionRoutine)');
# my $ret = $WSARecv->Call($s, $lpBuffers, $dwBufferCount, $lpNumberOfBytesRecvd, $lpFlags, $lpOverlapped, $lpCompletionRoutine);
# s : SOCKET -> WPARAM
# lpBuffers : WSABUF* -> LPVOID
# dwBufferCount : DWORD -> DWORD
# lpNumberOfBytesRecvd : DWORD* optional, out -> LPVOID
# lpFlags : DWORD* in/out -> LPVOID
# lpOverlapped : OVERLAPPED* optional, in/out -> LPVOID
# lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。関連項目
- f WSARecvEx — メッセージ境界情報付きでソケットからデータを受信する。
- f WSACloseEvent — イベントオブジェクトハンドルを閉じて解放する。
- f WSACreateEvent — 新しいイベントオブジェクトを作成する。
- f WSAGetOverlappedResult — オーバーラップ操作の完了結果を取得する。
- f WSASocketW — プロトコル情報やフラグを指定してソケットを作成する。
- f WSAWaitForMultipleEvents — 複数のイベントオブジェクトがシグナルになるまで待機する。
- f recv — 接続ソケットからデータを受信する。