ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TCP/IP 소켓 프로그래밍 - 15장 : 소켓과 표준 입출력
    네트워크 2024. 6. 25. 20:57

     

    15장

    15-1 표준 입출력 함수의 장점

     

    표준 입출력 함수가 지니는 장점은 다음과 같다.

    • 이식성이 좋다.
    • 버퍼링을 통해 성능을 향상 시킬 수 있다.

     

    표준 입출력 함수를 사용할 경우 추가적인 입출력 버퍼를 제공받는다.

    소켓의 버퍼와 입출력함수의 버퍼사이 관계를 그림으로 표현하면 아래와 같다.

     

    소켓 버퍼는 TCP의 목적 (신뢰성 )을 이루기 위해 재전송 역할도 맡는다.

    입출력 버퍼는 버퍼링을 통한 성능 향상만을 목적으로 한다.

     

     

    버퍼링은 전송하는 데이터의 양, 소켓 출력버퍼로의 데이터 이동횟수 측면에서 우월하다.

    여러번 나누어서 보내게 되면 고정크기의 헤더만큼의 추가적인 데이터가 생기게 되고,

     

     

    소켓 출력버퍼로의 이동에 걸리는 시간이 꽤 걸리기 때문에, 묶어서 처리하는 게 효율적이다.

     

     

    read & write와 같은 시스템 함수와 fputs& fgets 와 같은 표준 입출력 함수를 이용해

    파일 복사 프로그램을 만들어 성능을 비교해보자.

     

     

    10MB 크기의 txt 파일을 시스템 함수로 복사했을 때는 아래와 같이 6초 정도 걸린다.

     

     

    같은 크기의 txt 파일을 표준입출력 함수로 복사했을 때는 측정하기 힘들 정도로 금방 끝난다.

     

     

    read&write 함수는 버퍼를 제공하지 않는다는 것을 기억하자.

     

    표준 입출력 함수의 단점은 아래와 같다.

    • 양방향 통신이 쉽지 않다.
    • 상황에 따라 fflush 함수의 호출이 여러 번 등장해야 한다.
    • 파일 디스크립터를 FILE 구조체의 포인터로 변환해야 한다.

     

    파일을 열 때, 읽고 쓰기가 동시에 가능하려면 r+, w+, a+ 모드로 파일을 열어야 한다.

     

    버퍼링 문제로 인해 읽기에서 쓰기로, 또는 쓰기에서 읽기로 넘어갈 때마다

    fflush 함수를 호출해주어야 하는데,

    이렇게 되면 버퍼링으로 볼 수 있는 성능향상에 영향을 끼치게 된다.

     

     

    표준 입출력 함수를 사용하기 위해서는 FILE 구조체의 포인터가 필요하다.

    기본적으로 소켓 생성 시 파일 디스크립터를 반환하므로 이를 바꿔주어야 한다.

     

    //표준 입출력 함수로 복사하는 프로그램 예제일부
    
    FILE * fp1; FILE * fp2;
    
    //시스템 함수로 복사하는 프로그램 예제 일부
    
    int fd1; int fd2;

     


    15-2 표준 입출력 함수 사용하기

     

     

    fdopen 함수를 사용하면 파일 디스크립터를 FILE 포인터로 쉽게 변환할 수 있다.

    #include <stdio.h>
    
    FILE * fdopen(int fildes, const char* mode);
    //성공 시 변환된 FILE 구조체 포인터, 실패 시 NULL 리턴
    // mode : 파일 개방모드와 동일하다.

     

     

    아래는 fdopen 함수를 이용한 예제 코드이다.

    #include <stdio.h>
    #include <fcntl.h>
    
    int main(void)
    {
        FILE *fp;
        int fd = open("data.dat", O_WRONLY|O_CREAT|O_TRUNC);
    
        if(fd==-1)
        {
            fputs("file open error", stdout);
            return -1;
        }
    
        fp = fdopen(fd, "w");
        fputs("Network C programming \n", fp); //FILE 포인터를 얻어와 fputs함수를 호출함. 
        fclose(fp);  //FILE 포인터를 이용해 파일을 닫음. 
        return 0;
    }

     

     

    fdopen 함수의 반대 기능을 제공하는 함수로 fileno 함수가 있다.

    fileno 함수는 FILE 포인터를 인자로 받아 파일 디스크립터를 리턴한다.

    #include <stdio.h>
    
    int fileno(FILE * stream);
    //성공 시 변환된 파일 디스크립터, 실패 시 -1 리턴

     

    아래는 fileno 관련 예제 코드 실행 결과이다.

     

     


     

    15-3 소켓 기반에서의 표준 입출력 함수 사용

     

     

    주의할 점은 표준 입출력 함수는 성능 향상을 위해 버퍼링을 하기 때문에,

    fflush 함수를 호출하지 않으면, 당장에 클라이언트로 데이터가 전송됨을 보장할 수 없다.

     

     

    4장에서는 수신받은 데이터 마지막에 0을 넣어주어 문자열을 구성하는 과정이 필요했지만,

    표준 입출력 함수를 사용하게 되면서 문자열 단위로 데이터를 송수신하기 때문에

    그럴 필요가 없어졌다.

     

     

    표준 입출력 함수는,

    추가적인 코드의 발생때문에, 즐겨 사용되지는 않지만 때에 따라서는 유용하게 쓰일 수 있다.

    예제 실행 결과는 다음과 같다.

     

Designed by Tistory.