반응형
#include "CalServer.h" #define WIN32_LEAN_AND_MEAN // windows.h 에서 자주 사용하지 않은 것은 컴파일에서 제외 한다. // winsock2.h외의 충돌을 막아 준다. #include<stdio.h> #include<windows.h> #include<winsock2.h> #include<vector>// STL의 vector using namespace std; #pragma comment(lib, "ws2_32.lib") DWORD WINAPI MessageFun(void * mes) { SOCKET s = (SOCKET)mes; //클라이언트가 보내는 구조체를 수신한다. CALCPACKET packet; int total = sizeof(packet); // 수신해야 하는 크기 int current = 0; // 현재 수신한 총 크기 int nRead = 0; while(total < current) // 아직 다 받지 못한경우 { nRead = recv(s, (char*)&packet + current, total - current, 0); if(nRead > 0) { current += nRead; continue; // 계속 수신한다. } else if(nRead == 0) // 접속이 끊어 진 경우 { break; } else if(nRead < 0 ) // 수신 에러 발생 { break; } } //연산을 수행한다. int sum = 0; switch(packet.cmd) { case PLUS : sum = packet.first + packet.second; break; case MINUS : sum = packet.first - packet.second; break; case DIVIDE : sum = packet.first / packet.second; break; case MULTIPLY : sum = packet.first * packet.second; break; } //결과를 first에 넣어서 돌려준다. packet.first = sum; send(s, (char *)&packet, sizeof(packet), 0); closesocket(s); return 0; } void main() { WSADATA wsadata; //if(WSAStartup(0x0202, &wsadata) != 0) //0x0202는 뒤에서부터 읽어서 2.2버젼을 쓰라는 이야기다. if(WSAStartup(MAKEWORD(2,2), &wsadata) != 0) //많이 사용... 앞에서 부터 읽는다. { printf("Can't Initialize Socket !\n"); return ; } //------------------------------------------ //1. socket생성 : TCP: SOCK_STREAM : UDP :SOCK_DGRAM SOCKET s = socket(AF_INET, SOCK_STREAM, 0); //2. 생성된 소켓에 주소를 지정. SOCKADDR_IN addr = { 0 }; addr.sin_family = AF_INET; // 주소 종류 (AF_INET : IP 주소라는 의미.. addr.sin_port = htons(4000); //Port # addr.sin_addr.s_addr = inet_addr("61.81.99.54"); if(bind(s,(SOCKADDR*)&addr, sizeof(addr)) == -1) //서버의 닫혀 있는 상태를 대기 상태로 바꿔준다. 이순간 소켓은 내부적으로 접속요청 큐와 접속 완료 큐가 만들어진다. { printf("Can't bind \n"); return; } //3. 소켓을 대기 상태로 전환한다. if(listen(s, 5) == -1) { printf("Can't Listen\n"); return; } printf("클리이언트를 대기합니다. \n"); //4. 이제 Client 에서 부터 전달된 요청을 허용한다. while(1) { SOCKADDR_IN c_addr; int size = sizeof(c_addr); SOCKET c_s = accept(s, (SOCKADDR*)&c_addr, &size); //억셉트를 눌렀는데 대기 큐에 아무도 없으면 대기한다. //억셉트를 누르는 순간 새로운 소켓을 만들어서 //상태를 연걸상태로 //IP는 자신의 IP로 포트는 놀고있는 임의의 포트로 설정해준다.->4000번 포트로 접속해서 다른포트로 통신 //상대 IP와 상대 포트를 지정... 상대의 포트도 접속후에는 통신하는 포트로 지정한다. //->접속하는 소켓은 대기만하고 접속하면 새로운 소켓이 통신을 한다. printf("클라이언트가 접속했습니다. IP : %s\n", inet_ntoa(c_addr.sin_addr)); //새로운 스레드를 생성해서 클라이언트의 요청을 처리한다. HANDLE hThread = CreateThread(0 , 0, MessageFun, (void *)c_s, 0,0); CloseHandle(hThread); } //--------------------------------------------------------------------------- closesocket(s); // 소켓 닫기 //-------------------------------------------------------------- //------------------------------------------ WSACleanup(); }
#define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") struct MOUSE { int Message; POINTS point; WPARAM wParam; LPARAM lParam; }; char * server_ip = "61.81.99.56"; LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static SOCKET s; static SOCKADDR_IN addr; switch( msg ) { case WM_CREATE: s = socket(AF_INET, SOCK_DGRAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(7000); addr.sin_addr.s_addr = inet_addr(server_ip); return 0; case WM_KEYDOWN: case WM_KEYUP: { MOUSE mouse = {0}; mouse.Message = msg; mouse.wParam = wParam; mouse.lParam = lParam; sendto(s , (char *)&mouse, sizeof(mouse), 0, (SOCKADDR *)&addr, sizeof(addr)); } return 0; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEMOVE: { MOUSE mouse; mouse.Message = msg; mouse.point = MAKEPOINTS( lParam ); //서버로 보낸다. sendto(s , (char *)&mouse, sizeof(mouse), 0, (SOCKADDR *)&addr, sizeof(addr)); } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc( hwnd, msg, wParam, lParam); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { WSADATA wsadata; if ( WSAStartup( MAKEWORD(2,2), &wsadata) != 0 ) { MessageBox( 0, "Error", "", MB_OK); return 0; } ATOM atom; WNDCLASS wc; HWND hwnd; MSG msg; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground= (HBRUSH)GetStockObject( WHITE_BRUSH ); wc.hCursor = LoadCursor( 0, IDC_ARROW ); wc.hIcon = LoadIcon( 0, IDI_APPLICATION); wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.lpszClassName= "First"; wc.lpszMenuName = 0; wc.style = 0; atom = RegisterClass( &wc); if ( atom == 0 ) { MessageBox( 0, "Fail To RegisterClass", "Error", MB_OK); return 0; } hwnd = CreateWindowEx( 0, "first", "Hello", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT,0, 0, 0, hInstance, 0); ShowWindow( hwnd, nShowCmd); UpdateWindow( hwnd ); while ( GetMessage( &msg, 0, 0, 0) ) { TranslateMessage(&msg); DispatchMessage( &msg); } WSACleanup(); return 0; }
반응형
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."