Ejemplo n.º 1
0
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   SOCKET Accept;
   LPSOCKET_INFORMATION SocketInfo;
   DWORD RecvBytes, SendBytes;
   DWORD Flags;

   if (uMsg == WM_SOCKET)
   {
      if (WSAGETSELECTERROR(lParam))
      {
         printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
         FreeSocketInformation(wParam);
      } 
      else
      {
         switch(WSAGETSELECTEVENT(lParam))
         {
            case FD_ACCEPT:

               if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET)
               {		
                  printf("accept() failed with error %d\n", WSAGetLastError());
                  break;
               }

               // Create a socket information structure to associate with the
               // socket for processing I/O.

               CreateSocketInformation(Accept);

               printf("Socket number %d connected\n", Accept);

               WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);

               break;

            case FD_READ:

               SocketInfo = GetSocketInformation(wParam);

               // Read data only if the receive buffer is empty.

               if (SocketInfo->BytesRECV != 0)
               {
                  SocketInfo->RecvPosted = TRUE;
                  return 0;
               }
               else
               {
                  SocketInfo->DataBuf.buf = SocketInfo->Buffer;
                  SocketInfo->DataBuf.len = DATA_BUFSIZE;

                  Flags = 0;
                  if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
                     &Flags, NULL, NULL) == SOCKET_ERROR)
                  {
                     if (WSAGetLastError() != WSAEWOULDBLOCK)
                     {
                        printf("WSARecv() failed with error %d\n", WSAGetLastError());
                        FreeSocketInformation(wParam);
                        return 0;
                     }
                  } 
                  else // No error so update the byte count
                  {
                     SocketInfo->BytesRECV = RecvBytes;
                  }
               }

               // DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV. Go ahead
               // and begin writing data to the client.

            case FD_WRITE:   			

               SocketInfo = GetSocketInformation(wParam);

               if (SocketInfo->BytesRECV > SocketInfo->BytesSEND)
               {
                  SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;
                  SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;

                  if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,
                     NULL, NULL) == SOCKET_ERROR)
                  {
                     if (WSAGetLastError() != WSAEWOULDBLOCK)
                     {
                        printf("WSASend() failed with error %d\n", WSAGetLastError());
                        FreeSocketInformation(wParam);
                        return 0;
                     }
                  } 
                  else // No error so update the byte count
                  {
                     SocketInfo->BytesSEND += SendBytes;
                  }
               }

               if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)
               {
                  SocketInfo->BytesSEND = 0;
                  SocketInfo->BytesRECV = 0;

                  // If a RECV occurred during our SENDs then we need to post an FD_READ
                  // notification on the socket.

                  if (SocketInfo->RecvPosted == TRUE)
                  {
                     SocketInfo->RecvPosted = FALSE;
                     PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
                  }
               }

               break;

            case FD_CLOSE:

               printf("Closing socket %d\n", wParam);
               FreeSocketInformation(wParam);

               break;
         }
      }
      return 0;
   }

   return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    SOCKET sd;
    LPSOCKET_INFORMATION SocketInfo;
    DWORD RecvBytes, SendBytes;
    DWORD Flags;

    switch (Message) {
    case WM_CREATE:
        createElements(hwnd);
        break;
    case WM_SOCKET:
        if (WSAGETSELECTERROR(lParam)) {
            printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
            FreeSocketInformation(wParam);
        } else {
            switch (WSAGETSELECTEVENT(lParam)) {
            case FD_CONNECT:
                break;
            case FD_ACCEPT:
                if ((sd = accept(wParam, NULL, NULL)) == INVALID_SOCKET) {
                    break;
                }

                CreateSocketInformation(sd);
                
                WSAAsyncSelect(sd, hwnd, WM_SOCKET, FD_READ | FD_CLOSE);
                break;
            case FD_READ:
                SocketInfo = GetSocketInformation(wParam);

                // Read data only if the receive buffer is empty.

                if (SocketInfo->BytesRECV != 0) {
                    SocketInfo->RecvPosted = TRUE;
                    return 0;
                } else {
                    SocketInfo->DataBuf.buf = SocketInfo->Buffer;
                    SocketInfo->DataBuf.len = DATA_BUFSIZE;

                    Flags = 0;
                    if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
                        &Flags, NULL, NULL) == SOCKET_ERROR) {
                        if (WSAGetLastError() != WSAEWOULDBLOCK) {
                            printf("WSARecv() failed with error %d\n", WSAGetLastError());
                            FreeSocketInformation(wParam);
                            return 0;
                        }
                    } else { // No error so update the byte count
                        SocketInfo->BytesRECV = RecvBytes;
                    }
                    break;
                }
                break;
            case FD_WRITE:
                SocketInfo = GetSocketInformation(wParam);

                if (SocketInfo->BytesRECV > SocketInfo->BytesSEND) {
                    SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;
                    SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;

                    if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,
                        NULL, NULL) == SOCKET_ERROR) {
                        if (WSAGetLastError() != WSAEWOULDBLOCK) {
                            printf("WSASend() failed with error %d\n", WSAGetLastError());
                            FreeSocketInformation(wParam);
                            return 0;
                        }
                    }
                    else { // No error so update the byte count
                        SocketInfo->BytesSEND += SendBytes;
                    }
                }

                if (SocketInfo->BytesSEND == SocketInfo->BytesRECV) {
                    SocketInfo->BytesSEND = 0;
                    SocketInfo->BytesRECV = 0;

                    // If a RECV occurred during our SENDs then we need to post an FD_READ
                    // notification on the socket.

                    if (SocketInfo->RecvPosted == TRUE) {
                        SocketInfo->RecvPosted = FALSE;
                        PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
                    }
                }
                break;
            case FD_CLOSE:
                printf("Closing socket %d\n", wParam);
                FreeSocketInformation(wParam);
                break;
            }
        }
        break;
    case WM_DESTROY:	// Terminate program
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}