ホームに戻る
 WinSock(Non-Blocking Client)

Non-Blocking(非同期)通信は、
Win32 プログラミングにおいて待機時にウィンドウを止めないやり方です。
この方法を用いずスレッドを利用する方法もあります。

#include <windows.h>
#include <winsock2.h>

#define WSOCK_SELECT WM_USER + 1

#define WINDOW_CLASS_NAME "WinClassName"
#define WINDOW_NAME "WinName"

#define ID_B1 1000
#define IN_BUF_SIZE 256

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

static HINSTANCE g_hInst;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR, int nCmdShow)
{
  MSG msg;
  WNDCLASS wc;
  HWND hWnd;

  // Register Class
  if(hPrevInst == NULL)
  {
    ZeroMemory(&wc, sizeof(wc));
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
    wc.lpszClassName = WINDOW_CLASS_NAME;
    if(RegisterClass(&wc) == 0){
      return 0;
    }
  }

  g_hInst = hInst;

  // CreateWindow
  hWnd = CreateWindow(WINDOW_CLASS_NAME, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    (HWND)NULL, (HMENU)NULL, hInst, (LPVOID)NULL);
  if(hWnd == NULL){
    return 0;
  }

  // ShowWindow, UpdateWindow
  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  // Message Loop
  while(GetMessage(&msg, (HWND)NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
  static HWND hButton1;

  static SOCKET sock;
  static struct sockaddr_in serversockaddr;
  static char *SvName = "127.0.0.1";
  static unsigned short port = 12345;

  switch(uMsg){
    case WM_CREATE:
      WSADATA wsaData;
      unsigned long serveraddr;

      // Setting WinSock2
      if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0){
        return 0;
      }

      serveraddr = inet_addr((char *)SvName);
      if(serveraddr == INADDR_NONE){
        MessageBox(NULL, "error:inet_addr", "Error", MB_OK);
        PostMessage(hWnd, WM_DESTROY, 0, 0);
        break;
      }

      serversockaddr.sin_family = AF_INET;
      serversockaddr.sin_addr.s_addr = serveraddr;
      serversockaddr.sin_port = htons(port);

      memset(serversockaddr.sin_zero, 0, sizeof(serversockaddr.sin_zero));

      hButton1 = CreateWindow("BUTTON", "Button1",
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        10, 10, 80, 20, hWnd, (HMENU)ID_B1, g_hInst ,NULL);
      return 0;
    case WM_COMMAND:
      switch(LOWORD(wParam)){
        case ID_B1:
          sock = socket(PF_INET, SOCK_STREAM, 0);
          if(sock == INVALID_SOCKET){
            MessageBox(NULL, "error:socket", "Error", MB_OK);
            PostMessage(hWnd, WM_DESTROY, 0, 0);
            break;
          }
          if(WSAAsyncSelect(sock, hWnd, WSOCK_SELECT,
               FD_CONNECT | FD_WRITE | FD_READ | FD_CLOSE) == SOCKET_ERROR){  // FD_ACCEPT もあり
            MessageBox(NULL, "error:WSAAsyncSelect", "Error", MB_OK);
            PostMessage(hWnd, WM_DESTROY, 0, 0);
            break;
          }
          if(connect(sock, (struct sockaddr *)&serversockaddr, sizeof(serversockaddr)) == SOCKET_ERROR){
            if(WSAGetLastError() != WSAEWOULDBLOCK){
              MessageBox(hWnd, "error:connect", "Error", MB_OK);
            }
          }
          return 0;
        default:
          break;
      }
      break;
    case WSOCK_SELECT:
      if(WSAGETSELECTERROR(lParam) != 0){
        MessageBox(hWnd, "error:WSOCK_SELECT", "Error", MB_OK);
        closesocket(sock);
        break;
      }
      if(sock != wParam){
        break;
      }
      switch(WSAGETSELECTEVENT(lParam)){
        case FD_CONNECT: // connect
          break;
        case FD_WRITE: // send
          char *out_buf;
          out_buf = "abc";
          if(send(sock, out_buf, (int)strlen(out_buf), 0) == SOCKET_ERROR){
            if(WSAGetLastError() != WSAEWOULDBLOCK){
              MessageBox(hWnd, "error:send", "Error", MB_OK);
              closesocket(sock);
            }
            break;
          }
          break;
        case FD_READ: // receive
          int buf_len;
          char in_buf[IN_BUF_SIZE];
          buf_len = recv(sock, in_buf, IN_BUF_SIZE - 1, 0);
          if(buf_len == SOCKET_ERROR){
            MessageBox(hWnd, "error:recv", "Error", MB_OK);
            closesocket(sock);
            break;
          }
          in_buf[buf_len] = '\0';

          MessageBox(hWnd, (PCTSTR)in_buf, "Receive", MB_OK);
          break;
        case FD_CLOSE: // close
          WSAAsyncSelect(sock, hWnd, 0, 0);
          shutdown(sock, 2);
          closesocket(sock);
          sock = -1;
          break;
      }
      return 0;
    case WM_DESTROY:
      WSACleanup();
      PostQuitMessage(0);
      return 0;
  }

  return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

inserted by FC2 system