окна перекрытия IO модель

окна перекрытия IO модель

2019 Нянь 5 Юэ 29 Ri

11:58

   

В том же потоке под названием «перекрывают» IO IO к множеству перекрывающихся целевой передачи (или более целевой приема красного цвета) данных в результате. Для выполнения этой задачи, вызов функции ввода-вывода должны немедленно вернуться, единственный способ отправить обратно следующие данные.

Наиболее важное условие для перекрытия IO передачи и приема данных являются асинхронными IO.

В центре перекрытия IO IO не в самих окнах, но как проверить состояние завершения ввода-вывода. Потому что независимо от ввода или вывода, до тех пор, как в режиме без блокировки, необходимо подтвердить результаты других. Полученные результаты подтверждают необходимость пройти, прежде чем выполнять специальный процесс.

   

Создание перекрывающихся IO сокет

#include <winsock2.h>

РАЗЪЕМ WSASocket (интермедиат аф, тип INT, INT protocal, LPWSAPROTOCAL_INFO lpProtocolInfo, ГРУППА г, DWORD dwFlags);

- >> возврат дескриптором сокета на успех, неудача INVALID_SOCKET

   

аф информация набор протоколов

Разъем передачи типа данных

Протокол с использованием информации протокола сокета

lpProtocalInfo, содержащей информацию о сокете созданной структура WSAPROTOCAL_INFO значения переменного адреса, передать NULL, когда не требуется

г является функцией двух параметров расширенного резервирования, использовать 0

dwFlags сокет информации об атрибутах

   

Во-первых, создать перекрывающиеся разъем ввода-вывода, а затем использовать специальные функции ввода-вывода перекрываются передачи и приема данных, и подтверждает успешную передачу и прием данных посредством передачи и приема данных после того, как специальный метод или нет. Указанная функция после вас, и в случае необходимости для завершения регистрации в 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

   

с , когда гнездо ручка, ручка , имеющее гнездо перекрывается свойства передачи IO, выход модели для перекрытия IO

Адрес lpBuffers структура WSABUF значение переменного массива, WSABUF сохраненных данных, подлежащая передаче

dwBufferCount второй массив параметр длины

LpNumberOfBytesSent адрес переменной для хранения количества байтов, передаваемых

для изменения передачи данных характерных dwFlags

Адрес значение lpOverlapped WSAOVERLAPPED переменной структуры с помощью объекта события для завершения передачи данных подтверждения

lpCompletionRoutine входящего значения адреса функция Завершения Рутинного запись может быть получена путем сухой функцией, подтверждает ли передача данных

   

Структура определяется WSABUF

ЬурейаЯ структура __WSABUF

{

//; u_long Len размер данных, подлежащих передаче

обугливается FAR * БУФ; // значение адреса буфера

} WSABUF, * LPWSABUF;

   

Пример:

WSAEVENT событие;

WSAOVERLAPPED перекрывания;

WSABUF databuf;

обугливается ЬиЕ [BUF_SIZE] = { " данные, подлежащие передаче "};

INT recvBytes = 0;

...

Событие = WSACreateEvent ();

MemSet (& перекрываются, 0, SizeOf (перекрытый)); // все биты инициализируются 0

overlapped.hEvent = событие;

dataBuf.len = SizeOf (BUF);

dataBuf.buf = ЬиЕ;

WSASend (hSocket, & dataBuf, 1, & recvBytes, 0, & перекрывается, NULL);

...

   

WSAOVERLAPPEd структура определена следующим образом

ЬурейаЯ структура _WSAOVERLAPPE

{

DWORD Внутренний;

DWORD InternalHigh;

DWORD Offset;

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