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


+ Recent posts