- Server
- 1_server ~ 3_server
#define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <Windows.h> #include <WinSock2.h> #pragma comment (lib, "ws2_32.lib") int main() { WSADATA w; WSAStartup(MAKEWORD(2, 2), &w); //----------------------------------- // 1. 소켓 생성 SOCKET sock = socket(PF_INET, SOCK_STREAM, 0); // 2. 소켓에 주소 지정(bind) SOCKADDR_IN addr = { 0, }; addr.sin_family = AF_INET; addr.sin_port = htons(4000); addr.sin_addr.s_addr = INADDR_ANY; bind(sock, (SOCKADDR*)&addr, sizeof addr); // 3. 소켓을 대기 상태로, 5라는 arg는 무시 됨 listen(sock, 5); // 4. 클라이언트 요청을 수락 SOCKADDR_IN caddr = { 0, }; int sz = sizeof(caddr); SOCKET csock = accept(sock, (SOCKADDR*)&caddr, &sz); printf("클라이언트가 접속되었습니다.\n"); char buf[1024]; // 핵심 : read() 를 통해 수신하지 않습니다. 리턴값이 가장 중요하다. int ret; while (1) { ret = recv(csock, buf, 1024, 0); if (ret == 0) { printf("연결이 정상적으로 종료되었습니다.\n"); break; } else if (ret == -1) { printf("연결이 비정상적으로 종료되었습니다.\n"); break; } // ... ret = send(csock, buf, ret, 0); if (ret < 0) break; } printf("클라이언트가 접속이 해지되었습니다.\n"); closesocket(sock); closesocket(csock); //----------------------------------- WSACleanup(); }
Client
- 1_client
: 초기 셋팅, 주의 사항
// 1_client.cpp // 1. 윈도우즈의 모든 네트워크 관련 함수는 // winsock2.h에 있습니다. (헤더만) // 기존의 소켓 API를 확장한 형태 // 2.모든 구현은 sw2_32.dll에 있습니다. 링킹이 필요 // 3. Windows.h와 같이 사용할 경우 반드시 WinSock2.h를 먼저 // 포함해야 합니다. // 4. #define WIN32_LEAN_AND_MEAN // 5. 환경설정에서 링커 설정 // 3~5 중 선택적으로 사용 // Windows.h의 헤더에서 자주 사용하지 않는 것을 제외해달라. #define WIN32_LEAN_AND_MEAN #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") // 링킹 #include <Windows.h> // 모든 시스템 함수가 헤더파일에 선언되어 있습니다. int main() { return 0; }
- 2_client
#include <stdio.h> #include <WinSock2.h> #include <Windows.h> #pragma comment(lib, "ws2_32.lib") // 1. Network 함수를 사용하기 전에 WSAStartup을 통해 // 라이브러리 초기화를 수행해야 한다. // 2. WSA : Windows Socket API // 3. WSACleanup() 을 통해 자원을 정리해야 한다. int main() { // 찰스 시모니의 헝가리안 표기법 이해 필요, 변수명에 타입에 대한 정보가 나타남 // JAVA의 m~은? 안드로이드 표준 WSADATA w; int ret = WSAStartup(MAKEWORD(2, 2), &w); // 0x0202 word가 2byte if(ret != 0) printf("소켓 라이브러리를 사용할 수 없다.\n"); // w에 있는 정보는 현재까지 정확하지 않습니다. 사용되지 않습니다. printf("최대 소켓 갯수: %d\n", w.iMaxSockets); printf("소켓 버전: %d.%d\n", w.wHighVersion, w.wVersion); // 소켓 라이브러리가 사용하는 자원을 정리 WSACleanup(); }
- 3_client#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #include <Windows.h> #pragma comment(lib, "ws2_32.lib") #include <locale.h> int main() { setlocale(LC_ALL, "korean"); // 유니코드 셋팅 WSADATA w; WSAStartup(MAKEWORD(2, 2), &w); //-------------- // 1. 소켓 생성, 리눅스는 fd가 retrun, 윈도우는 SOCKET return SOCKET sock = socket(PF_INET, SOCK_STREAM, 0); // int도 되지만 정확한 타입을 사용! // 2. 서버 주소 지정 // struct sockaddr_in addr = { 0, }; SOCKADDR_IN addr = { 0, }; addr.sin_family = AF_INET; addr.sin_port = htons(4000); //addr.sin_port = htons(80); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //addr.sin_addr.s_addr = inet_addr("203.249.22.240"); // 3. 서버 접속 int ret = connect(sock, (SOCKADDR*)&addr, sizeof addr); if (ret == 0) printf("접속 성공\n"); else { int err = WSAGetLastError(); // 함수 호출하면 // 1. WSAGetLastError() / 도구 -> 오류 조희 printf("접속 실패 : %d\n", err); // 2. WSAGetLastError() 오류 번호를 저장하지 않고 다른 함수를 호출하면 오류 번호가 초기화 되버린다. WCHAR buf[512]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, LANG_SYSTEM_DEFAULT, buf, 512, 0); // L은 유니코드라는 표기 wprintf(L"에러 발생 : %s", buf); // 3. Debug Mode - 조사식 // @err // @err, hr // 비정상종료 테스트, 자원해지(소멸자 등) 테스트 //Sleep(1000 * 10); //exit(0); } //-------------- closesocket(sock); // close(sock); WSACleanup(); }
'Programing > Server Model' 카테고리의 다른 글
서버 모델 - 윈도우 IOCP (0) | 2016.02.26 |
---|---|
서버 모델 - 윈도우 Overlapped I/O (0) | 2016.02.26 |
서버 모델 - Event Driven I/O (0) | 2016.02.22 |
서버 모델 - I/O multiplexing (0) | 2016.02.22 |
서버 모델 - Synchronous Blocking I/O (0) | 2016.02.22 |