/*  デスクトップ送信実験サーバー 2003/ 5/16 宍戸 輝光 */ #include #include #include #pragma comment(lib, "wsock32.lib") /* VC++では、コメントをはずしてwinmm.libをリンク #pragma comment(lib, "winmm.lib") */ SOCKET sWait; LPBYTE lpPixels = NULL; HWND hwMain; BITMAPINFO biInfo; bool bSocket = false, bPixels = false; int iWidth, iHeight; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); DWORD WINAPI threadfunc(void *); int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine,int iCmdShow){ MSG msg; WNDCLASS wndclass; WSADATA wdData; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; RegisterClass(&wndclass); WSAStartup(MAKEWORD(1,1),&wdData); hwMain = CreateWindow("CWindow","デスクトップ送信実験", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT, 760,540,NULL,NULL,hInstance,NULL); ShowWindow(hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwMain); /* 再描画 */ while(GetMessage(&msg,NULL,0,0)) { /* メッセージループ */ TranslateMessage(&msg); DispatchMessage(&msg); } WSACleanup(); return msg.wParam ; } /* ウインドウプロシージャー */ LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static HANDLE hThread; static DWORD dwID; switch (iMsg) { /* メッセージを振り分ける */ case WM_CREATE: /* 通信スレッド生成 */ hThread = (HANDLE)CreateThread(NULL, 0, &threadfunc, NULL, 0, &dwID); return 0; case WM_PAINT: hdc=BeginPaint(hwnd, &ps); if (bPixels) { StretchDIBits(hdc, 0, 0, iWidth, iHeight, 0, 0, iWidth, iHeight, lpPixels, &biInfo, DIB_RGB_COLORS,SRCCOPY); } EndPaint(hwnd, &ps); return 0; case WM_DESTROY: /* ウインドウ破棄時 */ if (bSocket) { shutdown(sWait, 2); closesocket(sWait); } if (lpPixels !=NULL) { HeapFree(GetProcessHeap(), 0, lpPixels); } PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,iMsg,wParam,lParam); } /* 通信スレッド関数 */ DWORD WINAPI threadfunc(void *) { SOCKET sConnect; WORD wPort = 7000; int iLen, iRecvSize, iRecv, iGetSize = 1024; int iSize; char data; struct sockaddr_in saConnect, saLocal; char szBuf[1024], szTitle[128]; DWORD dwStart, dwEnd; sWait = socket(PF_INET, SOCK_STREAM, 0); ZeroMemory(&saLocal, sizeof(saLocal)); /* ポート7000番に接続待機用ソケット作成 */ saLocal.sin_family = AF_INET; saLocal.sin_addr.s_addr = INADDR_ANY; saLocal.sin_port = htons(wPort); if (bind(sWait, (LPSOCKADDR)&saLocal, sizeof(saLocal)) == SOCKET_ERROR) { closesocket(sWait); SetWindowText(hwMain, "接続待機ソケット作成失敗"); return 1; } if (listen(sWait, 2) == SOCKET_ERROR) { closesocket(sWait); SetWindowText(hwMain, "接続待機ソケット作成失敗"); return 1; } SetWindowText(hwMain, "接続待機ソケット作成成功"); iLen = sizeof(saConnect); /* sConnectに接続受け入れ */ sConnect = accept(sWait, (LPSOCKADDR)(&saConnect), &iLen); if (sConnect == INVALID_SOCKET) { shutdown(sConnect, 2); closesocket(sConnect); shutdown(sWait, 2); closesocket(sWait); SetWindowText(hwMain, "ソケット接続失敗"); return 1; } /* ソケット作成フラグセット */ bSocket = true; SetWindowText(hwMain, "ソケット接続成功"); iRecv = 0; /* 最初に8バイト受信 */ while (iRecv < 8) { iRecvSize = recv(sConnect, &data, 1, 0); if (iRecvSize > 0) { szBuf[iRecv] = data; iRecv += iRecvSize; } } /* 受信データから画像サイズを設定 */ iWidth = *(int *)szBuf; iHeight = *((int *)(szBuf + 4)); /* 画像データサイズを計算 */ iSize = iWidth * iHeight * 3; /* 画像データ用バッファ確保 */ lpPixels = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, iSize); data = 0; /* クライアントに応答 */ send(sConnect, &data, 1,0); iRecv = 0; SetWindowText(hwMain, "受信開始"); timeBeginPeriod(1); dwStart = timeGetTime(); /* 画像データ受信 */ while(iRecv < iSize) { /* 受信単位のサイズ計算 */ if (iGetSize > iSize - iRecv) { iRecvSize = iSize - iRecv; } else { iRecvSize = iGetSize; } /* データ受信 */ iRecvSize = recv(sConnect, szBuf, iRecvSize, 0); if (iRecvSize > 0) { CopyMemory(lpPixels + iRecv, szBuf, iRecvSize); iRecv += iRecvSize; } else { break; } } dwEnd = timeGetTime(); if (dwEnd - dwStart > 0) { wsprintf(szTitle, "受信ピクセルデータ(%d*%d):%dバイト受信完了 通信時間:%dms(%dKbps)", iWidth, iHeight, iRecv, dwEnd - dwStart, (iRecv * 8) / (dwEnd - dwStart)); } /* 文字列をタイトルに表示 */ SetWindowText(hwMain, szTitle); timeEndPeriod(1); shutdown(sConnect, 2); closesocket(sConnect); closesocket(sWait); /* DIB用BITMAPINFO構造体設定 */ biInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); biInfo.bmiHeader.biWidth = iWidth; biInfo.bmiHeader.biHeight = iHeight; biInfo.bmiHeader.biPlanes = 1; biInfo.bmiHeader.biBitCount = 24; biInfo.bmiHeader.biCompression = BI_RGB; biInfo.bmiHeader.biSizeImage = 0; biInfo.bmiHeader.biXPelsPerMeter = 0; biInfo.bmiHeader.biYPelsPerMeter = 0; biInfo.bmiHeader.biClrUsed = 0; biInfo.bmiHeader.biClrImportant = 0; /* 画像受信フラグセット */ bPixels = true; /* ウインドウ再描画 */ InvalidateRgn(hwMain, NULL, FALSE); UpdateWindow(hwMain); return 0; }