わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。

TCPサーバ

TCPサーバは、ソケットを生成してbindで待ち受けるだけです。 送信元の情報は、recvfromで受信する事で取得する事ができます。

#include <stdio.h>
#include <tchar.h>
#include <locale.h>
#include <string>
#include <winsock2.h>
#include <windows.h>
#include <wingdi.h>




// ライブラリ
#pragma comment( lib, "ws2_32.lib" )



// WinSockからのイベント
#define WM_WINSOCKEVENT ( WM_USER + 100 )



// グローバル
SOCKET oSocket;
SOCKET oSocketNew[ 10 ];



/*
	メインウインドウイベント処理
*/
LRESULT CALLBACK eMainWindowProc
(
	  HWND   hWnd   // handle to window
	, UINT   uMsg   // message identifier
	, WPARAM wParam // first message parameter
	, LPARAM lParam // second message parameter
)
{
	switch( uMsg ) {
	case WM_CREATE:
	//--------------------------------------------
	// WM_CREATE
	//--------------------------------------------
		{
			CREATESTRUCT* tpCreateSt = (CREATESTRUCT*)lParam;
			::ShowWindow( hWnd, SW_SHOW );
		}
		break;


	case WM_WINSOCKEVENT:
	//--------------------------------------------
	// WM_WINSOCKEVENT
	//--------------------------------------------
		{
			switch( WSAGETSELECTEVENT( lParam ) ) {
			case FD_ACCEPT:
				{
					struct sockaddr_in client;
					SOCKADDR_STORAGE sockAddr;
					int nAddrLen = sizeof(SOCKADDR_STORAGE);

					int len;

					// 接続許可
					SOCKET oNewSocket = ::accept(
							  oSocket
							, (struct sockaddr *)&sockAddr
							, &nAddrLen
						);
				}
				break;

			case FD_CLOSE:
				{
					::closesocket( (SOCKET)wParam );
				}
				break;


			case FD_CONNECT:
				{
				}
				break;

			case FD_READ:
				{
					SOCKET oNewSocket = (SOCKET)wParam;

					struct sockaddr_in oFromAddr;
					int sockaddr_in_size = sizeof( struct sockaddr_in );

					CHAR szData[ 256 ];

					// 受信
					::recv(
							  oNewSocket
							, (char*)szData
							, sizeof( szData ) - 1
							, 0
						);

					// 受信元IPと内容を表示
					printf( "%s¥n", szData );
				}
				break;
			}
		}
		break;


	case WM_LBUTTONDOWN:
	//--------------------------------------------
	// WM_LBUTTONDOWN
	//--------------------------------------------
		{
			struct sockaddr_in oSockAddr;
			oSockAddr.sin_family = AF_INET;
			oSockAddr.sin_port   = htons(12345);
			oSockAddr.sin_addr.S_un.S_addr = INADDR_ANY;
			oSockAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" );

			// ソケットの作成
			SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);

			// コネクト
			connect( sock, (struct sockaddr *)&oSockAddr, sizeof( oSockAddr ) );

			// 5文字送信
			send(sock, "HELLO", 6, 0);

			// TCPセッションの終了
			closesocket(sock);
		}
		break;


	case WM_DESTROY:
	//--------------------------------------------
	// WM_DESTROY
	//--------------------------------------------
		{
			// 終了する( 引数はそのまま終了コードとなります )
			::PostQuitMessage( 0 );
		}
		break;
	}

	// デフォルト処理呼び出し
	return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
}



/*
	TCPサーバ
*/
int _tmain
(
	  int argc
	, _TCHAR* argv[]
)
{
	// 標準出力にユニコードを表示できるようにする
	setlocale( LC_ALL, "Japanese" );

	// WinSockのスタートアップ
	WSAData tWsaData;
	WSAStartup( MAKEWORD(2,0), &tWsaData );

	WNDCLASSEX tWndClass;
	HINSTANCE  hInstance;
	TCHAR*     cpClassName;
	TCHAR*     cpWindowName;
	HWND       hWnd;


	// アプリケーションインスタンス
	hInstance    = ::GetModuleHandle( NULL );

	// クラス名称
	cpClassName  = _T("MainWindowClass");

	// ウインドウ名称
	cpWindowName = _T("TCPサーバ");

	// ウインドウクラスパラメータセット
	tWndClass.cbSize        = sizeof( WNDCLASSEX );
	tWndClass.style         = 0;
	tWndClass.lpfnWndProc   = eMainWindowProc;
	tWndClass.cbClsExtra    = 0;	// ::GetClassLong で取得可能なメモリ
	tWndClass.cbWndExtra    = 0;	// ::GetWindowLong で取得可能なメモリ
	tWndClass.hInstance     = hInstance; 
	tWndClass.hIcon         = NULL;
	tWndClass.hCursor       = NULL;
	tWndClass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
	tWndClass.lpszMenuName  = NULL;
	tWndClass.lpszClassName = cpClassName;
	tWndClass.hIconSm       = NULL;

	// ウインドウクラス生成
	if ( 0 == ::RegisterClassEx( &tWndClass ) ) {

		/* 失敗 */
		return( -1 );
	}

	// ウインドウを生成する(メッセージ専用)
	hWnd = ::CreateWindowEx (
		  0                       // extended window style
		, tWndClass.lpszClassName // pointer to registered class name
		, cpWindowName            // pointer to window name
		, WS_OVERLAPPEDWINDOW     // window style
		, CW_USEDEFAULT           // horizontal position of window
		, CW_USEDEFAULT           // vertical position of window
		, 640                     // window width
		, 480                     // window height
//		, HWND_MESSAGE            // handle to parent or owner window
		, NULL
		, NULL                    // handle to menu, or child-window identifier
		, hInstance               // handle to application instance
		, (VOID*)0x12345678       // pointer to window-creation data
	);


	// ソケットの生成
	oSocket = socket( AF_INET, SOCK_STREAM, 0 );

	// ソケットを非同期にする
	WSAAsyncSelect( oSocket, hWnd, WM_WINSOCKEVENT, FD_CONNECT | FD_READ | FD_CLOSE );

	struct sockaddr_in oSockAddr;
	oSockAddr.sin_family = AF_INET;
	oSockAddr.sin_port   = htons( 12345 );
	oSockAddr.sin_addr.S_un.S_addr = INADDR_ANY;

	// バインド
	::bind( oSocket, (struct sockaddr*)&oSockAddr, sizeof( oSockAddr ) );

	 // TCPクライアントからの接続要求を待てる状態にする
	::listen( oSocket, 10 );

	 /*
		メッセージループ
	*/
	MSG        tMsg;
	while( 0 != ::GetMessage( &tMsg, NULL, 0, 0 ) ) {
		::TranslateMessage ( &tMsg );
		::DispatchMessage ( &tMsg );
	}
	// メッセージループ
//	::MessageBox( NULL, L"受信待ち", L"受信待ち", MB_OK );

	// ソケットのクローズ
	::closesocket( oSocket );

	// WinSockのクリーンナップ
	::WSACleanup();

	// 正常終了
	return( 0 );
}



実行結果






わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。