네트워크 프로그래밍 15 소켓과 표준 입출

zh025700·2022년 6월 6일
0

네트워크 프로그래밍

15. 소켓과 표준 입출력

시스템 function call vs 표준 입출력

시스템 함수

  • read()
  • write()
  • open()
  • close()

표준 입출력

  • fopen()
  • fclose()
  • fdopen()
  • fileno()

표준 입출력

  • 파일이 읽히거나 쓰이기 전에, 라이브러리 기능에 의해 열린다
  • fopen
    • "data.txt"와 같은 외부 이름; 하우스키핑 및 운영 체제와의 협상을 수행
    • 파일의 다음 읽기 또는 쓰기 작업에 사용할 포인터를 반환

fopen으로 반환되는 포인터는 FILE이라 불리는 자료형이다
FILE* fp;

표준 입출력 함수의 장점

이식성이 좋다

  • ANSI C에서 표준으로 정의했기 때문에 모든 컴파일러에서 지원한다

버퍼링을 통한 성능 향상에 도움이 된다

  • 표준 입출력 함수를 사용하면 기본 소켓의 입출력 버퍼 + 추가적 입출력 버퍼를 제공받는다
    • 표준 입출력 함수를 사용해 데이터를 전송할 경우 2개의 버퍼를 거치게 된다
      • 소켓 버퍼: TCP 구현을 위한 목적
        • 데이터 분실 시, 재 전송을 위해 데이터 저장을 위한 버퍼
      • 표준 입출력 함수 버퍼: 성능 향상

버퍼링을 하면 성능이 많이 좋아 지나??

  • 데이터 양이 많을 수록 버퍼링에 따른 성능 차이는 크다!

    • 전송되는 데이터 양, 출력 버퍼로의 데이터 이동 횟수 관점

ex

패킷을 보낼때는 헤더 정보가 추가되어 보내는 데이터 크기에 상관없이 일정한 크기를 가진다
그래서 전송해야 할 데이터 양에는 큰 차이가 나게된다

- 1 바이트 데이터를 10번에 걸쳐서 보내는 경우

    1바이트 X 10회: 40 X 10 = 400바이트

- 1 바이트 데이터를 버퍼링해 10바이터로 묶어서 보내는 경우

    10바이트 X 1회: 40 X 1 = 40바이트

보내야하는 데이터의 양이 10배나 차이가 난다
1바이트를 10회 이동 시키는 시간이 10바이트를 1번 이동시키는 것보다 10배 더 느리다

표준 입출력 함수의 단점

  • 양방향 통신이 쉽지 않다
  • 상황에 따라 fflush() 호출이 빈번히 등장할 수 있다
    • 버퍼링 문제로 인해 작업의 형태를 바꿀때마다 fflush()를 호출해야함 fput -> fget
      • 이렇게 되면 버퍼링 기반 성능 향상에 영향을 끼친다
  • 파일 디스크립터를 FILE 포인터로 변환해야한다
    • 기본적으로 소켓은 생성시 파일 디스크립터를 반환
      • 이를 파일 포인터로 변환해야함

표준 입출력 함수와 시스템 함수의 성능 비교

 파일 디스크립터를 활용해 read, write를 통한 파일 복사보다
 파일 포인터를 통해 fgets, fputs를 이용한 파일 복사가 훨씬 빠르다

 파일의 크기가 커질수록 차이가 난다

표준 입출력 함수 사용

소켓 생성 시에는 파일 디스크립터가 반환된다.
표준 입출력 함수를 사용하려면 이를 파일 포인터로 변환해야한다.

fdopen을 통한 파일 포인터로 변환

fdopen을 통하면 디스크립터 -> 파일 포인터로 변환 가능하다

FILE* fdopen(int fd,const char* mode)

fp = fdopen(fd,"w")
  • 성공 시 변환된 파일 구조체 포인터 실패시 NULL
  • fd: 변환할 파일 디스크립터
  • mode: 생성할 파일 포인터의 모드 정보
    • 읽기모드인 r, 쓰기모드인 w

fileno 함수를 통한 파일 디스크립터로의 변환

fileno를 사용하면 파일 포인터를 파일 디스크립터로 변환한다

int fileno(FILE* straem);

fileno(fp);
  • 성공시 변환된 파일 디스크립터 반환, 실패시 -1
  • stream: 변환하려는 파일 포인터

소켓기반에서 표준 입출력 함수 사용

  • 소켓 파일 디스크립터를 파일 포인터로 바꾼다
    • 이때 포인터를 여는 모드를 신경써준다
      • read: r
      • write: w

서버

 소켓으로 부터 읽어오는 데이터가 없을때까지 통신을 하기 위해서
 기존에는 소켓에서 읽어오는 데이터가 없을때까지 반복 조건을 뒀음
 파일 포인터를 사용하면 비슷하게 !feof(포인터)를 사용하면 됨
 fflush를 사용해야 바로 클라이언트에 데이터가 전송이 된다.
 그렇지 않는다면 데이터를 모아서 보내기 때문에 바로 전송이 안된다


 fflush없이 통신하면 오류남.... 안되더랑....

클라이언트에선 파일 포인터 변경 후 모드에 맞는 포인터를 사용하는 것만 주의하면 됨

표준 입출력 함수들

  • 파일 오픈
    • fopen()
  • 파일 닫기
    • fclose()
  • 읽기
    • fget()
    • getc()
    • fgets()
    • gets()
  • 쓰기
    • fputc()
    • putc()
    • fputs()
    • puts()
profile
정리

1개의 댓글

comment-user-thumbnail
2022년 6월 11일

태그가 어떤건 네트워크 프로그래밍이고 어떤건 네트워크프로그래밍이네요..
거슬리니 하나로 통일해주세요

답글 달기