[Network] 1. C++ 기본 Winsock 에코(echo) 클래스 제작
프로그래밍 언어/C++2009. 12. 28. 15:56
Winsock을 이용한 기본 에코 서버/클라이언트 구현에 필요한 간단한 CNetworkSession클래스 입니다. 공부하시는분은 참고가 되었으면 좋겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #pragma once #include "winsock2.h" #pragma comment(lib, "ws2_32.lib") class CNetworkSession { protected: WSADATA wsaData; SOCKET mySocket; SOCKET acceptSocket; sockaddr_in myAddress, clntAddr; CNetworkSession(); ~CNetworkSession(); public: int SendData(char* buffer); int RecvData(char* buffer, int size); }; class Server : public CNetworkSession { public: void Start(const char *ipAddress, int port); }; class Client : public CNetworkSession { public: void Connect(const char *ipAddress, int port); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include "stdafx.h" #include "CNetworksession.h" ///////////////////////////////////////////////////////// // Parent Class Network Basic Settings // ///////////////////////////////////////////////////////// CNetworkSession::CNetworkSession() { if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { cerr << "WSAStartup() Error!" << endl; WSACleanup(); exit(1); } mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(mySocket == INVALID_SOCKET) { cerr << "socket() Error!" << endl; WSACleanup(); exit(1); } acceptSocket = SOCKET_ERROR; ZeroMemory(&myAddress, sizeof(SOCKADDR_IN)); } CNetworkSession::~CNetworkSession() { if(mySocket != INVALID_SOCKET) { closesocket(mySocket); } WSACleanup(); } int CNetworkSession::SendData(char* buffer) { return send(mySocket, buffer, strlen(buffer), 0); } int CNetworkSession::RecvData(char* buffer, int size) { int len = recv(mySocket, buffer, size, 0); buffer[len] = NULL; return len; } ///////////////////////////////////////////////////////// // Server Start (bind, listen, accept) // ///////////////////////////////////////////////////////// void Server::Start(const char *ipAddress, int port) { myAddress.sin_family = AF_INET; myAddress.sin_port = htons(port); myAddress.sin_addr.S_un.S_addr = inet_addr(ipAddress); if(bind(mySocket, (SOCKADDR*)&myAddress, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { cerr << "bind() Error!" << endl; WSACleanup(); exit(1); } if(listen(mySocket, 1) == SOCKET_ERROR) { cerr << "listen() Error!" << endl; WSACleanup(); exit(1); } do { // int len = sizeof(clntAddr); // acceptSocket = accept(mySocket, (SOCKADDR*)&clntAddr, &len); acceptSocket = accept(mySocket, NULL, NULL); } while (acceptSocket == SOCKET_ERROR); mySocket = acceptSocket; } ///////////////////////////////////////////////////////// // Client Connect() Start // ///////////////////////////////////////////////////////// void Client::Connect(const char *ipAddress, int port) { myAddress.sin_family = AF_INET; myAddress.sin_port = htons(port); myAddress.sin_addr.S_un.S_addr = inet_addr(ipAddress); if(connect(mySocket, (SOCKADDR*)&myAddress, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { cerr << "connect() Error!" << endl; WSACleanup(); exit(1); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | // CNetwork_test.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다. // #include "stdafx.h" enum TYPE{ServerMode, ClientMode, Quit}; int _tmain(int argc, _TCHAR* argv[]) { int nSelect = 0; char buffer[256]; char *ipAddress = "127.0.0.1"; int port = 9999; cout << "1 Server Mode" << endl; cout << "2 Client Mode" << endl; cout << "3 Quit" << endl << ">"; cin >> nSelect; switch(nSelect-1) { case ServerMode: // Server Mode { cout << "Start Server Mode !!\n"; Server s; s.Start(ipAddress, port); while(s.RecvData(buffer, sizeof(buffer)) != 0) { if(strncmp(buffer, "exit", 4) == 0) exit(0); cout << "C_MSG : " << buffer << endl; s.SendData(buffer); } break; } case ClientMode: // Client Mode { cout << "Start Client Mode !!\n\n"; Client c; c.Connect(ipAddress, port); while(1) { // input type is two. // 1. cin.ignore() + cin.get() // 2. fgets() + fflush() cin.ignore(); cout << "input : "; cin.get(buffer, sizeof(buffer)); //2 fgets(buffer, sizeof(buffer), stdin); input to stdin //2 fflush(stdin); stdin buffer trath c.SendData(buffer); c.RecvData(buffer, sizeof(buffer)); cout << "S_MSG : " << buffer << endl; if(strncmp(buffer, "exit", 4) == 0) exit(0); } break; } case Quit: // Quit cout << "Quit to This Program.." << endl; exit(0); break; default: cout << "Error Exit" << endl; break; } return 0; } |
CNetworkSession에서 기본적인 소켓초기화 등을 다 해결해주고 상속된 서버/클라이언트 클래스에서 구체적인 기능만 정의하여 사용하였습니다.
프로그램의 기능은 간단히 에코기능만 넣어서 작동되도록 하였습니다. 즉 클라에서 서버로 전송된 데이터는 다시 클라이언트로 반환합니다.
'프로그래밍 언어 > C++' 카테고리의 다른 글
[IOCP] 리스트와 iocp를 이용한 Echo서버 소스 (0) | 2010.01.26 |
---|---|
[API] System Error 메시지 사용하기 WSAGetLastError() (0) | 2010.01.20 |
1. DLL(Dynamic Linking Library) 제작 및 사용하기 (10) | 2009.12.18 |
Mysql API / C/C++ 연동하기 강좌 (7. ODBC를 이용한 mysql 연동하기) (5) | 2009.12.17 |
Mysql API / C/C++ 연동하기 강좌 (6. mysql c++클래스 연동 예제 / 도서관리) (4) | 2009.12.15 |