Static 변수의 특징

  • 다른 변수와 마찬가지로 해당하는 가장 윗 부분에 선언된다.
  • 전역 변수 처럼 '0' 으로 초기화 된다.
  • 함수가 끝나도 해당 값이 파괴되지 않는다.
  • 저장되는 메모리 영역은 전역 변수가 저장되는 정적 데이터 영역
  • 지역변수와 마찬가지로 해당 함수 안에서만 사용이 가능하다.

Static 변수의 특징을 잘 알아볼 수 있는 예제를 이용하여 정확히 파악

#include <stdio.h>

void printCount(void);

int main(void)
{
    int i;

    for(i = 0; 10 >= i; i++)
    {
        printCount();
    }
    
    return 0;
}

void printCount(void)
{
    static int i;

    printf("%d\n", i);
    i = i + 1;
    
    return;
}

함수 printCount 안의 변수인 i는 함수가 종료되어도 파괴되지 않고 값을 유지하고 있다. 



전역변수에서 static을 선언해 주면 다른 파일에서 해당 변수를 extern으로 건다해도 참조 할 수 없다.


저작자 표시
신고

'컴퓨터 언어 > C' 카테고리의 다른 글

pThread를 이용한 Thread  (0) 2013.03.05
Static 변수  (0) 2013.02.25
메세지 기법  (0) 2013.01.16
배열의 이름은 첫번째 원소의 주소이다.  (0) 2012.12.20
문자열, 그것은 배열.  (2) 2012.06.11
Makefile을 작성하자.  (2) 2012.06.10

socket()

서버와 통신할 때 사용할 소켓을 생성할 수 있는 함수.

int s_socket;

s_socket = socket(PF_INET, SOCK_STREAM, 0);
if(-1 == s_socket)
{
    printf("Failed to make the socket\n");
    return (-1);
}
  • 헤더
    • #include <sys/types.h>
    • #include <sys/socket.h>

  • 형태
    • int socket(int domain, int type, int protocol);

  • 인수
    • int domain, 인터넷을 통해 통신할 지, 같은 시스템 내에서 프로세스 끼리 통신할지
      • PF_INET, AF_INET
        • IPv4 인터넷 프로토콜을 사용
      • PF_INET6
        • IPv6 인터넷 프로토콜을 사용
      • PF_LOCAL, AF_UNIX
        • 같은 시스템 내에서 프로세스 끼리 통신
      • PF_PACKET
        • Low level socket을 인터페이스로 사용
      • PF_IPX
        • IPX 노벨 프로토콜을 사용합니다.
    • int type, 데이터의 전송 형태를 지정
      • SOCK_STREAM
        • TCP/IP 프로토콜을 이용
      • SOCK_DGRAM
        • UDP/IP 프로토콜을 이용
    • int  protocol, 통신에 있어 특정 프로토콜 사용을 지정하기 위한 변수, 보통 0

  • 반환 값
    • -1 이외는 소켓 식별자
    • -1 은 실패



저작자 표시
신고

서버 프로그램

네트워크 연결 장치인 소켓을 생성하여 포트를 할당하고, 해당 포트로 클라이언트로부터의 연결 요청이 들어오면 즉시 연결, 준비된 문자열인 "Hello World"를 클라이언트측에 전송하도록 구현.



#include <stdio.h>     
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 9000               /* 포트를 9000번으로 명시 */

char buffer[BUFSIZ] = "hello, world\n"; /* 보낼 문자열 */

int main()
{
    int c_socket;
    int s_socket;

    struct sockaddr_in s_addr;
    struct sockaddr_in c_addr;

    int len;
    int n;

    /* 클라이언트로 부터 연결 요청을 받을 수 있도록 Socket 함수를 이용,
     * 네트워크 연결 장치인 소켓을 생성한다.*/
    s_socket = socket(PF_INET, SOCK_STREAM, 0);

    /* 클라이언트로 부터 연결 요청을 받을 서버 IP주소와 포트를 설정
     * 9000번 포트로 들어오는 모든 연결 요청에 대해 응용프로그램에서 처리하겠다는 의미 */
    memset(&s_addr, 0, sizeof(s_addr));
    s_addr.sin_addr.s_addr =    htonl(INADDR_ANY);
    s_addr.sin_family =         AF_INET;
    s_addr.sin_port =           htons(PORT);

    /* 생성한 소켓을 해당 포트와 연결 */
    if(bind(s_socket, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1)
    {
        printf("Can not Bind\n");
        return -1;
    }

    /* 커널에 해당 소켓으로 통신이 이루어지도록 요청
     * 이 시점 이후로 해당 포트로 요청하는 연결을 받아들인다.*/
    if(listen(s_socket, 5) == -1)
    {
        printf("listen Fail\n");
        return -1;
    }

    /* 무한 루프 */
    while(1)
    {
        /* 클라이언트로 부터 연결 요청을 받아 들이는 코드
         * 전화 오기를 기다리다가 비로서 수화기를 들어 받는 단계 */
        len = sizeof(c_addr);
        c_socket = accept(s_socket, (struct sockaddr *) &c_addr, &len);
        
        /* 클라이언트와 연결된 연결 소켓(c_socket)으로 문자열 hello world를
         * 보낸다. */
        n = strlen(buffer);
        write(c_socket, buffer, n);

        /* 클라이언트에 연결된 연결 소켓(c_socket)을 끊고, 클라이언트로 부터 새로운
         * 연결 요청이 오기를 듣기 소켓(s_socket)을 이용하여 기다린다.*/
        close(c_socket);
    }
    close(c_socket);
        
    return 0;
}

사용된 주요 함수

  • 소켓을 생성
    • socket()
  • 연결 요청을 수신할 주소 설정
  • 소켓을 포트에 연결
    • blind()
  • 커널에 개통을 요청
    • listen()
  • 연결 요청을 수신
    • accept()
  • 클라이언트에게 서비스를 제공
    • read() / write()
  • 클라이언트와의 연결을 종료
    • close()

서버 프로그램만으로는 어떠한 결과 화면도 볼 순 없다. 다만 프로그램 자체는 정상적으로 소켓을 만들고 설정한 뒤 무한루프 안의 accept() 함수가 클라이언트의 연결 요청을 기다리고 있다.

아직 클라이언트 프로그램을 만들지 않았기 때문에 Telnet을 이용하여 간단하게 확인해 보았다. 서버가 잘 동작하는 것을 확인할 수 있다.

저작자 표시
신고