Return to Tech

TCP SERVER

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

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

#define WM_SOCKET WM_APP

SOCKET InitSocket(LPSTR lpszPort);
int GetSocketIdx(SOCKET soc, SOCKET socServer[], int nMaxSocCount);
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 SERVER");
 HWND hwnd;
 MSG msg;
 WNDCLASSEX 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(&wcex) == 0)
  return 0;

 hwnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW,
  0, 0, 640, 480, 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 int nMaxSocCount = 10;
 static SOCKET socListen = INVALID_SOCKET;
 static SOCKET socServer[10];
 static HWND hwndListBox = NULL;

 switch(uMsg) {
  case WM_CREATE:{
   int i;
   hwndListBox = CreateWindowEx(0, TEXT("LISTBOX"),
    NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL, 0, 0, 0, 0,
    hWnd, (HMENU)1, ((LPCREATESTRUCT)lP)->hInstance, NULL);

   socListen = InitSocket("49999");
   if(socListen == INVALID_SOCKET)
    return -1;

   for(i = 0; i < nMaxSocCount; i++)
    socServer[i] = INVALID_SOCKET;

   WSAAsyncSelect(socListen, hWnd, WM_SOCKET, FD_ACCEPT);

   return 0;
  }

  case WM_SOCKET:
   switch(WSAGETSELECTEVENT(lP)) {
    case FD_ACCEPT: {
     int i;
     int nAddrLen;
     char szBuf[256];
     char szHostName[256];
     SOCKADDR_STORAGE sockAddr;

     i = GetSocketIdx(INVALID_SOCKET, socServer, nMaxSocCount);

     nAddrLen = sizeof(SOCKADDR_STORAGE);
     socServer[i] = accept(socListen, (LPSOCKADDR)&sockAddr, &nAddrLen);
     WSAAsyncSelect(socServer[i], hWnd, WM_SOCKET, FD_READ | FD_CLOSE);
     getnameinfo((LPSOCKADDR)&sockAddr, nAddrLen, szHostName, sizeof(szHostName), NULL, 0, 0);
     wsprintfA(szBuf, "No%d(%s)Connected", i + 1, szHostName);
     SendMessageA(hwndListBox, LB_ADDSTRING, 0, (LPARAM)szBuf);

     break;
    }

    case FD_READ: {
     int i;
     int nLen;
     int nResult;
     TCHAR szBuf[256];
     TCHAR szData[256];

     i = GetSocketIdx((SOCKET)wP, socServer, nMaxSocCount);

     nLen = sizeof(szData);
     nResult = recv(socServer[i], (char *)szData, nLen, 0);

     wsprintf(szBuff, TEXT("No%d %s"), i + 1, szData);

     SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)szBuff);

     nLen = nResult;

     nResult = send(socServer[i], (char *)szData, nLen, 0);

     break;
    }

    case FD_CLOSE: {
     int i;
     TCHAR szBuf[256];

     i = GetSocketIdx((SOCKET)wP, socServer, nMaxSocCount);

     wsprintf(szBuf, TEXT("No%d Disconnected"), i + 1);
     SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)szBuf);

     shutdown(socServer[i], SD_BOTH);
     closesocket(socServer[i]);
     socServer[i] = INVALID_SOCKET;

     break;
    }
   } // end of switch(WSAGETSELECTEVENT
   return 0;

  case WM_SIZE:
   MoveWindow(hwndListBox, 0, 0, LOWORD(lP), HIWORD(lP), TRUE);
   return 0;

  case WM_DESTROY: {
   int i;
   for(i = 0; i < nMaxSocCount; i++) {
    if(socServer[i] != INVALID_SOCKET) {
     shutdown(socServer[i], SD_BOTH);
     closesocket(socServer[i]);
    }
   }

   if(socListen != INVALID_SOCKET) {
    closesocket(socListen);
    WSACleanup();
   }

   PostQuitMessage(0);
   return 0;
  }

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

SOCKET InitSocket(LPSTR lpszPort) {
 WSADATA wsaData;
 ADDRINFO addrHints;
 LPADDRINFO lpAddrList;
 SOCKET socListen;

 WSAStartup(MAKEWORD(2, 2), &wsaData);

 ZeroMemory(&addrHints, sizeof(addrinfo));
 addrHints.ai_family = AF_INET;
 addrHints.ai_socktype = SOCK_STREAM;
 addrHints.ai_protocol = IPPROTO_TCP;
 addrHints.ai_flags = AI_PASSIVE;

 if(getaddrinfo(NULL, lpszPort, &addrHints, &lpAddrList) != 0) {
  MessageBox(NULL, TEXT("Failed to get address info"), NULL, MB_ICONWARNING);
  WSACleanup();
  return INVALID_SOCKET;
 }

 socListen = socket(lpAddrList->ai_family, lpAddrList->ai_socktype,
  lpAddrList->ai_protocol);

 if(bind(socListen, lpAddrList->ai_addr, (int)lpAddrList->ai_addrlen) == SOCKET_ERROR) {
  MessageBox(NULL, TEXT("bind error"), NULL, MB_ICONWARNING);
  closesocket(socListen);
  freeaddrinfo(lpAddrList);
  WSACleanup();
  return INVALID_SOCKET;
 }

 if(listen(socListen, 1) == SOCKET_ERROR) {
  MessageBox(NULL, TEXT("Listen error"), NULL, MB_ICONWARNING);
  closesocket(socListen);
  freeaddrinfo(lpAddrList);
  WSACleanup();
  return INVALID_SOCKET;
 }

 freeaddrinfo(lpAddrList);

 return socListen;
 
}

int GetSocketIdx(SOCKET soc, SOCKET socServer[], int nMaxSocCount) {
 int i;

 for(i = 0; i < nMaxSocCount; i++) {
  if(socServer[i] == soc)
   break;
 }

 return i;
}

Return to Tech