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