窓のオーバーラップIOモデル

窓のオーバーラップIOモデル

2019 インディアン 5 29 Riを

11時58分

   

重複目標伝達(または赤色を受ける複数の標的)の複数のIO「IOと重なる」と呼ばれる同じスレッド内のデータが引き起こされます。このタスクを達成するために、IO関数を呼び出すと、すぐに次のデータを返送するための唯一の方法を返す必要があります。

IOは送受信データが重複するための最も重要な前提条件は、非同期IOです。

IO IOの重複の焦点は、Windows自体ではなく、IO完了の状態を確認する方法。かかわらず、入力または出力限り、非ブロッキングモードの、別の結果を確認する必要があるからです。結果は、特別な処理を実行する前に通過する必要性を確認します。

   

重なり合う作成IO ソケットを

書式#include <winsock2.h>

SOCKETのやWSASocket(INTのAF、int型、INT protocal、LPWSAPROTOCAL_INFO lpProtocolInfo、グループg、DWORD dwFlagsパラメータ)。

- >> 成功、失敗のリターンソケットハンドルINVALID_SOCKET

   

AF プロトコルスイートの情報

ソケット型データ伝送

ソケットプロトコル情報を使用してプロトコル

必要のないときWSAPROTOCAL_INFO構造変数のアドレス値を作成したソケット情報を含んlpProtocalInfoは、NULLを渡します

gが使用0、拡張予約の二つのパラメータの関数です。

dwFlagsパラメータソケット属性情報

   

まず、重複IOソケットを作成し、データを送受信重なる特別なIO機能を使用するために、送信及び特別な方法か後にデータを受信することによって成功したデータの送受信を確認します。あなたの後に必要に応じて指定された機能が実行を通じてIOの登録を完了します。

   

実行オーバーラップIO のWSASendの機能

書式#include <winsock2.h>

int型のWSASend(SOCKET sの、LPWSABUF lpBuffers、DWORD dwBufferCount、

LPDWORD lpNumberOfBytesSent、DWORD dwFlagsパラメータ、

LPWSAOVERLAPPED lpOverlapped、

LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)。

- >> 成功のリターン0が失敗した場合に返されSOCKET_ERROR

   

S ソケットハンドル、ソケットを有するハンドルは、IOと重複するIO伝達特性、モデル出力を重畳しました

アドレスlpBuffers WSABUF構造可変配列値、記憶されたデータが送信されるWSABUF

dwBufferCount第2の長さパラメータ配列

バイトの数を記憶するLpNumberOfBytesSent可変アドレスは、実際に送信さ

データ伝送特性dwFlagsパラメータを変更するには

アドレス値は、データ送信確認完了のイベントオブジェクトを使用してWSAOVERLAPPED構造変数をlpOverlapped

lpCompletionRoutine着信アドレス値完了ルーチンのエントリ関数は、乾燥機能することにより製造することができるデータ転送か否かを確認します

   

構造が定義されているWSABUF

typedefは構造体__WSABUF

{

//; u_longのLEN データのサイズを送信します

FAR char型* bufは; // バッファのアドレス値

} WSABUF、* LPWSABUF。

   

例:

WSAEVENTイベント。

WSAOVERLAPPEDを重ね、

WSABUFのdatabuf。

チャーBUF [BUF_SIZE] = { " のデータが送信されます"}。

int型によりrecvbytes = 0;

...

イベント= WSACreateEvent()。

memset(&重ね、0、はsizeof (重複)); // すべてのビットに初期化される0

overlapped.hEvent =イベント。

dataBuf.len =はsizeof(BUF)。

dataBuf.buf = BUF。

WSASend(hSocket、&dataBuf、1、&によりrecvbytes、0、&重ね、NULL);

...

   

WSAOVERLAPPEd 次のように構造が定義されています

typedefは構造体_WSAOVERLAPPE

{

DWORD内部;

DWORD InternalHigh;

DWORDオフセット。

DWORD OffsetHigh;

WSAEVENT hEvent;

} WSAOVERLAPPED、* LPWSAOVERLAPPED。

内部、InternalHigh IOを重ねたときに、オフセット内部で使用されるオペレーティングシステムのメンバー、OffsetHighも特別な目的を持って、実際には唯一のhEventメンバーに焦点を当てる必要があります

   

あなたが重複パラメータにnullを渡すと、動作するソケットは、道をブロックされています。同様に、のWSASendを用いて伝達関数の複数の対象データと、各ターゲットは、単独で構造体変数を有する必要があるWSAOVERLAPPED

   

还具有一种情况就是在WSASend调用结束立即返回的同时,数据也同时传输完成。在这个时候WSASend函数返回0,同时在recvBytes中填充发送的字节数。反之(数据没有传输完成),WSASend仍需传输数据时,将返回SOCKET_ERROR,并将WSA_IO_PENDING(尚未完成状态Pending)注册为错误代码(错误代码通过WSAGetLastError获得)。之后通过WSAGetOverlappedResult获取实际传输大小。

   

执行重叠IOWSARecv函数

#include <winsock2.h>

int WSARecv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,

LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags,

LPWSAOVERLAPPED lpOverlapped,

LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);

->>成功时返回0,失败时返回SOCKET_ERROR

   

s 赋予重叠IO属性的套接字句柄

lpBuffers 用于保存接收数据的WSABUF结构体数组地址值

dwBufferCount 向第二个参数传递的数组的长度

lpNumberOfBytesRecvd 保存接收数据大小信息的地址值

lpFlags 用于设置或读取传输特性信息

lpOverlapped WSAOVERLAPPED结构体变量地址

lpCompletionRoutine Completion Routine函数地址

   

Gather/Scatter I/O是指将多个缓冲区中的数据积累到一定程度后一次型传输(Gather输出),将接收的数据分批保存(Scatter输入)。Linux下的writev&readv函数具有Gather/Scatter I/O功能,但是windows下并没有这些函数的定义。不过可以通过重叠IO中的WSASend和WSARecv函数获得类似的功能。他们的第二个参数和第三个参数中就可以判断出其具有Gather/Scatter I/O功能。

   

获得实际传输大小

#include <winsock2.h>

BOOL WSAGetOverlappedResult(SOCKET s, LPWSAOVERLAPPED lpOverlapped,

LPDWORD lpcbTreansfer, BOOL fWait, LPDWORD lpdwFlags);

->>成功时返回TRUE,失败时返回FALSE

   

s 重叠IO套接字

lpOverlapped WSAOVERLAPPED结构体变量地址

lpcbTransfer 用于保存实际传输字节数的变量地址

fWait 如果调用该函数时仍在进行IO,是否等待IO完成,TRUE等待,FALSE不等待(返回FALSE并跳出函数)。

lpdwFlags 用于获取附加信息(如OOB消息)。如果不需要,可以传递NULL

   

重叠IOIO完成确认

重叠IO中有两种方法确认IO的完成并获取结果

  • 利用WSASend、WSARecv函数的第六个参数,基于事件对象
  • 利用WSASend、WSARecv函数的第七个参数,基于Completion Routine

   

使用前一种方法时需要注意:

  • 完成IO时,WSAOVERLAPPED结构体变量引用的事件对象将编程为signaled状态
  • 为了验证IO的完成和完成结构,需要调用WSAGetOverlappedResult函数

   

使用Completion Routine函数

可以通过WSARecv&WSASend函数的最后一个参数中指定的Completion Routine(以下简称CR)函数验证IO完成情况。

   

"注册CR"有如下含义:"Pending的IO完成以后调用此函数"

但是如果执行重要任务时突然调用Completion Routine,则有可能会破坏程序的正常执行流。因此操作系统通常都会预先定义规则:"只有请求I/O的线程处于alertalble wait状态时才能调用Completion Routine函数"

   

"alertable wait状态"时等待接收操作系统消息的线程状态,调用以下函数可以进入alertable wait状态

  • WaitForSingleObjectEx
  • WaitForMultipleObjectsEx
  • WSAWaitForMultipleEvents
  • SleepEx

   

第一,第二,第四个参数提供的功能与WaitForSingleObject,WaitForMultipleObjects,Sleep函数相同,只是额外增加了1个参数。如果该参数为TRUE,则相应线程进入alertable wait状态

第三个函数的最后一个参数设置为TRUE时,线程同样进入alertable wait状态。

   

启动IO任务后,执行完紧急任务时可以调用上述任意函数验证IO完成与否,此时操作系统知道线程进入alertable wait状态,如果有已经完成的IO。则调用相应的Completion Routine函数。调用以后上述函数将全部返回WAIT_IO_COMPLETION,并开始执行接下来的程序

   

Completion Routine函数原型

void CALLBACK CompletionROUTINE(DWORD dwError, DWORD cbTransferred,

LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags);

   

参数一 中写入错误信息(正常结束时写入0)

参数二 写入实际收发的字节数

参数三 写入WSASend,WSARecv函数的参数lpOverlapped

dwFlags 写入调用IO函数时传入的特性信息或者0

   

   

  

おすすめ

転載: www.cnblogs.com/freesfu/p/10943508.html