ホームに戻る
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);
}