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 |