Return to Tech

TCP CLIENT

以下のソースを入力し cl, linkしてみましょう。
cmd> cl -c TcpClient.cpp
cmd> link TcpClient.obj user32.lib gdi32.lib
file: tcpclient.cpp
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

#define ID_SEND 100
#define ID_EDIT 200

WSAEVENT g_hEventExit = NULL;

SOCKET InitSocket(LPSTR lpszServerName, LPSTR lpszPort);
DWORD WINAPI ThreadProc(LPVOID lpParam);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wP, LPARAM lP);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
 LPSTR lpszCmdLine, int nCmdShow) {
 TCHAR szAppName[] = TEXT("TCP CLIENT");

 HWND hwnd;
 MSG msg;

 WNCDCLASSEX wcex;

 wcex.cbSize = sizeof(WNDCLASSEX);
 wcex.style = 0;
 wcex.lpfnWndProc = WindowProc;
 wcex.cbClsExtra = 0;
 wcex.cbWndExtra = 0;
 wcex.hInstance = hInst;
 wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 wcex.lpszMenuName = NULL;
 wcex.lpszClassName = szAppName;
 wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

 if(RegisterClassEx(&wc) == 0)
  return 0;

 hwnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW,
  0, 0, 320, 240, NULL, NULL, hInst, NULL);
 if(hwnd == NULL)
  return 0;

 ShowWindow(hwnd, nCmdShow);
 UpdateWindow(hwnd);

 while(GetMessage(&msg, NULL, 0, 0) > 0) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wP, LPARAM lP) {
 static HWND hwndButton = NULL;
 static HWND hwndEdit = NULL;
 static HANDLE hThread = NULL;
 static SOCKET soc = INVALID_SOCKET;
 switch(uMsg) {
  case WM_CREATE: {
   DWORD dwThreadId;
   hwndButton = CreateWindowEx(0, TEXT("BUTTON"), TEXT("Send"),
    WS_CHILD | WS_VISIBLE, 10, 10, 60, 30, hwnd,
    (HMENU)ID_SEND, ((LPCREATESTRUCT)lP)->hInstance, NULL);
   hwndEdit = CreateWindowEx(0, TEXT("EDIT"), TEXT("Message to send"),
    WS_CHILD | WS_VISIBLE | WS_BORDER, 90, 10, 300, 35, hwnd,
    (HMENU)ID_EDIT, ((LPCREATESTRUCT)lP)->hInstance, NULL);

   soc = InitSocket("localhost", "49999");
   if(soc == INVALID_SOCKET)
    return -1;

   g_hEventExit = WSACreateEvent();

   hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, &soc, 0, &dwThreadId);
   return 0;
  }

  case WM_COMMAND: {
   int nLen;
   int nResult;
   TCHAR szData[256];

   if(LOWORD(wP) != ID_SEND)
    return 0;

   nLen = GetWindowText(hwndEdit, szData, sizeof(szData));
   nLen = (nLen + 1) * sizeof(TCHAR);

   nResult = send(soc, (char *)szData, nLen, 0);
   if(nResult == SOCKET_ERROR)
    MessageBox(NULL, TEXT("send error"), NULL, MB_ICONWARNING);

   return 0;
  }

  case WM_DESTROY: {
   if(Thread != NULL) {
    WSASetEvent(g_hEventExit);
    WaitForSingleObject(hThread, 1000);
    CloseHandle(hThread);
    WSACloseEvent(g_hEventExit);
   }

   if(soc != INVALID_SOCKET) {
    shutdown(soc, SD_BOTH);
    closesocket(soc);
    WSACleanup();
   }

   PostQuitMessage(0);
   return 0;
  }

  default:
   break;
 }
 return DefWindowProc(hwnd, uMsg, wP, lP);
}

DWORD WINAPI ThreadProc(LPVOID lpParam) {
 SOCKET soc = *(SOCKET *)lpParam;

 DWORD dwResult;
 WSAEVENT hEvent;
 WSAEVENT hEventArray[2];
 WSANETWORKEVENTS events;

 hEvent = WSACreateEvent();
 WSAEventSelect(soc, hEvent, FD_READ | FD_CLOSE);

 hEventArray[0] = hEvent;
 hEventArray[1] = g_hEventExit;

 for(;;) {
  dwResult = WSAWaitForMultipleEvents(2, hEventArray,
   FALSE, WSA_INFINITE, FALSE);
  if(dwResult == WSA_WAIT_FAILED)
   break;

  if(dwResult - WSA_WAIT_EVENT_0 == 0) {
   WSAEnumNetworkEvents(soc, hEvent, &events);

   if(events.lNetworkEvents & FD_CLOSE) {
    MessageBox(NULL, TEXT("connection closed"), TEXT("OK"), MB_OK);
    break;
   } else if(events.lNetworkEvents & FD_READ) {
    int nLen;
    int nResult;

    TCHAR szBuf[256];
    TCHAR szData[256];

    nLen = sizeof(szData);

    nResult = recv(soc, (char *)szData, nLen, 0);
    wsprintf(szBuf, TEXT("%dbyte received\n%s"), nResult, szData);
    MessageBox(NULL, szBuf, TEXT("OK"), MB_OK);

   } else 
    ;
   WSAResetEvent(hEvent);
  } else if(dwResult - WSA_WAIT_EVENT_0 == 1)
   break;
  else
   ;
 }

 WSACloseEvent(hEvent);

 return 0;
}

SOCKET InitSocket(LPSTR lpszServerName, LPSTR lpszPort) {
 WSADATA wsaData;
 ADDRINFO addrHints;
 LPADDRINFO lpAddrList;
 SOCKET soc;

 WSAStartup(MAKEWORD(2, 2), &wsaData);
 ZeroMemory(&addrHints, sizeof(addrinfo));
 addrHints.ai_family = AF_INET;
 addrHints.ai_socktype = SOCK_STREAM;
 addrHints.ai_protocol = IPPROTO_TCP;

 if(getaddrinfo(lpszServerName, lpszPort, &addrHints, &lpAddrList) != 0) {
  MessageBox(NULL, TEXT("Failed to get hostinfo.."), NULL, MB_ICONWARNING);
  WSACleanup();

  return INVALID_SOCKET;
 }

 soc = socket(lpAddrList->ai_family, lpAddrList->ai_socktype, lpAddrList->ai_protocol);
 if(connect(soc, lpAddrList->ai_addr, (int)lpAddrList->ai_addrlen) == SOCKET_ERROR) {
  int nError = WSAGetLastError();
  if(nError == WSAECONNREFUSED)
   MessageBox(NULL, TEXT("Connection refused."), NULL, MB_ICONWARNING);
  else if(nError == WSAEHOSTUNREACH)
   MessageBox(NULL, TEXT("Unreachable."), NULL, MB_ICONWARNING);
  else
   MessageBox(NULL, TEXT("Failed to connect"), NULL, MB_ICONWARNING);

  freeaddrinfo(lpAddrList);
  closesocket(soc);
  WSACleanup();
  return INVALID_SOCKET;
 }

 freeaddrinfo(lpAddrList);

 return soc;
}

Return to Tech