zoukankan      html  css  js  c++  java
  • windows重叠I/O模型

    重叠I/O就相当于异步I/O。

    一、重叠I/O的I/O完成确认

    1、使用事件对象

    接收端:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <WinSock2.h>
     4 
     5 #define BUF_SIZE 1024
     6 void ErrorHandling(char *message);
     7 
     8 int main(int argc, char *argv[])
     9 {
    10     if (argc != 2) {
    11         printf("Usage : %s <port>
    ", argv[0]);
    12         exit(1);
    13     }
    14 
    15     WSADATA wsaData;
    16     SOCKET hLinSock, hCRecvSock;
    17     SOCKADDR_IN lisnAdr, recvAdr;
    18     int recvAdrSz;
    19     
    20     WSABUF dataBuf;
    21     WSAEVENT evObj;
    22     WSAOVERLAPPED overlapped;
    23 
    24     char buf[BUF_SIZE];
    25     int recvBytes = 0, flags = 0;
    26 
    27     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    28         ErrorHandling("WSAStartup() error.");
    29 
    30     hLinSock = socket(PF_INET, SOCK_STREAM, 0);
    31     memset(&lisnAdr, 0, sizeof(lisnAdr));
    32     lisnAdr.sin_family = AF_INET;
    33     lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY);
    34     lisnAdr.sin_port = htons(atoi(argv[1]));
    35 
    36     if (bind(hLinSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR)
    37         ErrorHandling("bind() error.");
    38     if (listen(hLinSock, 5) == SOCKET_ERROR)
    39         ErrorHandling("listen() error.");
    40 
    41     recvAdrSz = sizeof(recvAdr);
    42     hCRecvSock = accept(hLinSock, (SOCKADDR*)&recvAdr, &recvAdrSz);
    43 
    44     evObj = WSACreateEvent();
    45     memset(&overlapped, 0, sizeof(overlapped));
    46     overlapped.hEvent = evObj;
    47     dataBuf.len = BUF_SIZE;
    48     dataBuf.buf = buf;
    49     
    50     if (WSARecv(hCRecvSock, &dataBuf, 1, (LPDWORD)&recvBytes, (LPDWORD)&flags, &overlapped, NULL) == SOCKET_ERROR)
    51     {
    52         if (WSAGetLastError() == WSA_IO_PENDING)
    53         {
    54             puts("Background data receive");
    55             WSAWaitForMultipleEvents(1, &evObj, TRUE, WSA_INFINITE, FALSE);
    56             WSAGetOverlappedResult(hCRecvSock, &overlapped, (LPDWORD)&recvBytes, FALSE, NULL);
    57         }
    58         else{
    59             ErrorHandling("WSARECV() error");
    60         }
    61     }
    62 
    63     printf("Received message: %s
    ", buf);
    64     WSACloseEvent(evObj);
    65     closesocket(hCRecvSock);
    66     closesocket(hLinSock);
    67     WSACleanup();
    68     return 0;
    69 }
    70 
    71 void ErrorHandling(char *message) {
    72     fputs(message, stderr);
    73     fputc('
    ', stderr);
    74 }
    75 
    76 void CompressSockets(SOCKET hSockArr[], int idx, int total){
    77     for (int i = idx; i < total; i++)
    78         hSockArr[i] = hSockArr[i + 1];
    79 }
    80 
    81 void CompressEvents(WSAEVENT hEventArr[], int idx, int total){
    82     for (int i = idx; i < total; i++)
    83         hEventArr[i] = hEventArr[i + 1];
    84 }
    View Code

    发送端:

     1 #pragma warning(disable:4996)
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     5 #include <winsock2.h>
     6 
     7 void ErrorHandling(char *message);
     8 
     9 int main(int argc, char* argv[]) {
    10     if (argc != 3) {
    11         printf("Usage : %s <IP> <port>
    ", argv[0]);
    12         exit(1);
    13     }
    14 
    15     WSADATA wsaData;
    16     SOCKET hSocket;
    17     SOCKADDR_IN sendAdr;
    18 
    19     WSABUF dataBuf;
    20     char msg[] = "Network is Computer!";
    21     int sendBytes = 0;
    22 
    23     WSAEVENT evObj;
    24     WSAOVERLAPPED overlapped;
    25 
    26     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    27         ErrorHandling("WSAStartup() error");
    28 
    29     hSocket = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    30     memset(&sendAdr, 0, sizeof(sendAdr));
    31     sendAdr.sin_family = AF_INET;
    32     sendAdr.sin_addr.s_addr = inet_addr(argv[1]);
    33     sendAdr.sin_port = htons(atoi(argv[2]));
    34 
    35     if (connect(hSocket, (SOCKADDR*)&sendAdr, sizeof(sendAdr)) == SOCKET_ERROR)
    36         ErrorHandling("connect() error");
    37     else
    38         printf("Connected.......
    ");
    39 
    40     evObj = WSACreateEvent();
    41     memset(&overlapped, 0, sizeof(overlapped));
    42     overlapped.hEvent = evObj;
    43     dataBuf.len = strlen(msg) + 1;
    44     dataBuf.buf = msg;
    45 
    46     if (WSASend(hSocket, &dataBuf, 1, (LPDWORD)&sendBytes, 0, &overlapped, NULL) == SOCKET_ERROR){
    47         if (WSAGetLastError() == WSA_IO_PENDING){
    48             puts("Background data send");
    49             WSAWaitForMultipleEvents(1, &evObj, TRUE, WSA_INFINITE, FALSE);
    50             WSAGetOverlappedResult(hSocket, &overlapped, (LPDWORD)&sendBytes, FALSE, NULL);
    51         }
    52         else{
    53             ErrorHandling("WSASend() error");
    54         }
    55     }
    56     printf("Send data size:%d
    ", sendBytes);
    57     WSACloseEvent(evObj);
    58     closesocket(hSocket);
    59     WSACleanup();
    60     return 0;
    61 }
    62 
    63 void ErrorHandling(char *message) {
    64     fputs(message, stderr);
    65     fputc('
    ', stderr);
    66 }
    View Code

    2、基于Completion Routine

    接收端:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <WinSock2.h>
     4 
     5 #define BUF_SIZE 1024
     6 void ErrorHandling(char *message);
     7 void CALLBACK CompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD);
     8 
     9 WSABUF dataBuf;
    10 char buf[BUF_SIZE];
    11 int recvBytes = 0;
    12 
    13 int main(int argc, char *argv[])
    14 {
    15     if (argc != 2) {
    16         printf("Usage : %s <port>
    ", argv[0]);
    17         exit(1);
    18     }
    19 
    20     WSADATA wsaData;
    21     SOCKET hLinSock, hRecvSock;
    22     SOCKADDR_IN lisnAdr, recvAdr;
    23     
    24     WSAEVENT evObj;
    25     WSAOVERLAPPED overlapped;
    26 
    27     int idx, recvAdrSz, flags = 0;
    28 
    29     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    30         ErrorHandling("WSAStartup() error.");
    31 
    32     hLinSock = socket(PF_INET, SOCK_STREAM, 0);
    33     memset(&lisnAdr, 0, sizeof(lisnAdr));
    34     lisnAdr.sin_family = AF_INET;
    35     lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY);
    36     lisnAdr.sin_port = htons(atoi(argv[1]));
    37 
    38     if (bind(hLinSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR)
    39         ErrorHandling("bind() error.");
    40     if (listen(hLinSock, 5) == SOCKET_ERROR)
    41         ErrorHandling("listen() error.");
    42 
    43     recvAdrSz = sizeof(recvAdr);
    44     hRecvSock = accept(hLinSock, (SOCKADDR*)&recvAdr, &recvAdrSz);
    45     if (hRecvSock == INVALID_SOCKET)
    46         ErrorHandling("accept() error");
    47 
    48     
    49     memset(&overlapped, 0, sizeof(overlapped));
    50 
    51     dataBuf.len = BUF_SIZE;
    52     dataBuf.buf = buf;
    53 
    54     evObj = WSACreateEvent();
    55     
    56     if (WSARecv(hRecvSock, &dataBuf, 1, (LPDWORD)&recvBytes, (LPDWORD)&flags, &overlapped, CompRoutine) == SOCKET_ERROR)
    57     {
    58         if (WSAGetLastError() == WSA_IO_PENDING)
    59         {
    60             puts("Background data receive");
    61         }
    62         else{
    63             ErrorHandling("WSARECV() error");
    64         }
    65     }
    66 
    67     idx = WSAWaitForMultipleEvents(1, &evObj, FALSE, WSA_INFINITE, TRUE);
    68     if (idx == WAIT_IO_COMPLETION)
    69         puts("Overlapped I/O Completed");
    70     else
    71         ErrorHandling("WSARecv() error");
    72     WSACloseEvent(evObj);
    73     closesocket(hRecvSock);
    74     closesocket(hLinSock);
    75     WSACleanup();
    76     return 0;
    77 }
    78 
    79 void CALLBACK CompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags){
    80 
    81     if (dwError != 0){
    82         ErrorHandling("CompRoutine error");
    83     }
    84     else{
    85         recvBytes = szRecvBytes;
    86         printf("Received message: %s
    ", buf);
    87     }
    88 }
    89 
    90 void ErrorHandling(char *message) {
    91     fputs(message, stderr);
    92     fputc('
    ', stderr);
    93 }
    View Code

    发送端:同上

  • 相关阅读:
    SSAS没有注册类别 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) 解决办法
    Javascript中暂停功能的实现
    【转】JQuery ajax json 实例
    SqlDataAdapter有关InsertCommand,UpdateCommand,DeleteCommand 实例
    绑定数组对象DataTable.Select返回值DataRow[]
    SQL SERVER 联想函数重写
    JQuery Dialog(转)
    温习C 文件操作
    轻松掌握Windows窗体间的数据交互
    反射方法调用时的一个错误:参数计数不匹配( parameter count mismatch )
  • 原文地址:https://www.cnblogs.com/ACGame/p/10633963.html
Copyright © 2011-2022 走看看