336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
소켓 통신 #2 - AF_INET 사용하기 (3)
- by Tapito
소켓을 사용하기 위해 서버와 클라이언트 모두 각 단계별로 실행할 함수에 대해 알아보았습니다. 이를 종합하여 완성된 소스는 다음과 같습니다. Linux/Unix 에서는 잘 작동 될 것이라 생각되지만, Windows 사용자는 잘 작동이 안될 수 있습니다. WinSock이라는 약간 다른 함수를 사용하기 때문입니다.
/* server.c */ int main(int argc, char * argv[]) { /* 자기 자신의 포트와 IP 주소 */ struct sockaddr_in sockaddrServer; /* sockaddrServer 구조체 인스턴스의 크기 */ int sockaddrServerLength = sizeof(sockaddr_in); /* 자기 자신의 서버용 소켓 */ SOCKET sockServer; /* 자신에게 접속해 온 클라이언트의 포트와 IP 주소 */ struct sockaddr_in sockaddrClient; /* sockaddr */ int sockaddrClientLength = 0; /* 클라이언트로부터 얻은 소켓 */ SOCKET sockClient; /* 소켓 함수 실행 결과 */ int status; /* -------- 1 단계 -------- */ /* sockaddr_in 구조체를 사용하기 전에 항상 구조체의 모든 내용을 0으로 초기화합니다. */ memset(&sockaddrServer, 0, sizeof(struct sockaddr_in)); /* 인터넷 망에 접속 */ sockaddrServer.sin_family = AF_INET; /* 서버이므로 접속 대상이 없음 */ sockaddrServer.sin_addr.s_addr = htonl(INADDR_ANY); /* 포트 번호는 1435로 */ sockaddrServer.sin_port = htons((u_short)1435); /* -------- 2 단계 -------- */ printf("creating socket...\n"); /* 인터넷망에 접속하며 스트림 방식으로 데이터를 교환하는 소켓 생성 */ sockServer = socket(AF_INET, SOCK_STREAM, 0); if (sockServer == INVALID_SOCKET) { printf("Invalid Socket in step 2\n"); return -1; } printf("socket created.\n"); /* -------- 3 단계 -------- */ printf("binding...\n"); /* sockaddr_in 구조체와 생성한 소켓을 연결하여 서버용 소켓으로 이용함 */ status = bind(sockServer, (struct sockaddr *)&sockaddrServer, sizeof(struct sockaddr_in)); if (status == SOCKET_ERROR) { printf("Socket Error in step 3\n"); return -1; } printf("bound.\n"); /* -------- 4 단계 -------- */ printf("listening...\n"); /* 연결 대기 상태로 만들기 */ status = listen(sockServer, 5); if (status == SOCKET_ERROR) { printf("Socket Error in step 4\n"); closesocket(sockServer); // 오류 시 서버용 소켓 닫기 return -1; } printf("listened. %d\n", WSAGetLastError()); /* -------- 5 단계 -------- */ /* 클라이언트로부터 넘어오는 sockaddr_in 구조체도 마찬가지로 사용 전 0으로 초기화 */ memset(&sockaddrClient, 0, sizeof(struct sockaddr_in)); sockaddrClientLength = sizeof(struct sockaddr_in); /* 접속을 요청한 1명의 소켓 얻기 */ sockClient = accept(sockServer, (struct sockaddr *)&sockaddrClient, &sockaddrClientLength); if (sockClient == INVALID_SOCKET) { printf("Invalid Socket in step 5\n"); closesocket(sockServer); // 오류 시 서버용 소켓 닫기 return -1; } /* 접속자 정보 확인 */ printf("Accessed from %s:%d (sockaddr = %d bytes)\n", inet_ntoa(sockaddrClient.sin_addr), (int)ntohs(sockaddrClient.sin_port), sockaddrClientLength); /* 클라이언트와 서버 소켓 순으로 닫고 프로그램 종료 */ closesocket(sockClient); closesocket(sockServer); return 0; }
 
한편 클라이언트용 소켓은
/* client.c */ int main(int argc, char * argv[]) { /* 접속 대상의 포트와 IP 주소 */ struct sockaddr_in sockaddrServer; /* sockaddrServer 구조체 인스턴스의 크기 */ int sockaddrServerLength = sizeof(sockaddr_in); /* 서버에 접속할 용도로 만든 소켓 */ SOCKET sockServer; /* 소켓 함수 실행 결과 */ int status; /* -------- 1 단계 -------- */ memset(&sockaddrServer, 0, sockaddrServerLength); sockaddrServer.sin_family = AF_INET; sockaddrServer.sin_addr.s_addr = inet_addr("127.0.0.1"); sockaddrServer.sin_port = htons((u_short)1435); /* -------- 2 단계 -------- */ sockServer = socket(AF_INET, SOCK_STREAM, 0); if (sockServer == INVALID_SOCKET) { printf("Invalid Socket in step 2\n"); closesocket(sockServer); return -1; } /* -------- 3 단계 -------- */ status = connect(sockServer, (struct sockaddr *)&sockaddrServer, sizeof(struct sockaddr_in)); if (status == SOCKET_ERROR) { printf("Socket Error in step 3\n"); closesocket(sockServer); return -1; } closesocket(sockServer); return 0; }
'Programming Language > C&C++' 카테고리의 다른 글
소켓 함수를 사용하여 도메인을 IP주소간 상호 변환하기 (0) | 2014.11.05 |
---|---|
소켓 통신 #2 - AF_INET 사용하기 (4) (0) | 2014.09.20 |
소켓 통신 #2 - AF_INET 사용하기 (2) (0) | 2014.09.19 |
소켓 통신 #2 - AF_INET 사용하기 (1) (0) | 2014.09.19 |
소켓 통신 #1 - 소켓 통신에 쓰이는 구조체 (2) | 2014.09.19 |