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;
}