Using Standard I/O on Sockets

Slides:



Advertisements
Similar presentations
TCP 서버/클라이언트 동작 원리 - (1) TCP 서버/클라이언트 예 웹 서버 웹 클라이언트 웹 클라이언트
Advertisements

1.
Java Socket 통신 이개혁 정대준.
[ 단원 12 ] 파일처리 부산대학교 남 태 우.
Understanding of Socket and File I/O
13장 소켓.
Chapter 06. UDP 서버/클라이언트.
-Part3- 제3장 콘솔 입출력과 파일 입출력.
C 프로그래밍 소개 숙명여대 창병모 2011 가을.
TCP/IP Socket Cover Slide 조태문.
TCP/IP 소켓 프로그래밍 - C 버전 중에서
Department of Computer Engineering
TUXEDO 프로그래밍 가이드.
4장. 소켓 유형과 프로토콜 Network Lab. 이 원 구 1.
PHP 웹 프로그래밍 (PHP Web Programming) 네트워크 프로그래밍 문양세 강원대학교 IT대학 컴퓨터과학전공.
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
Department of Computer Engineering
제 18 장 TCP/IP 연결 확립과 종료 정보통신연구실.
TCP Client/Server Program
Network Lab. Seoung Hyeon, Lee
얇지만 얇지 않은 TCP/IP 소켓 프로그래밍 C 2판
호스트이름과 네트워크이름 찾기 (Hostname and Network Name Lookups)
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
Part 14 파일 입출력 ©우균, 창병모 ©우균, 창병모.
6장 비연결형 지향 프로토콜 Database Lab 강 우 석.
인터넷 주소 변환 School of Electronics and Information. Kyung Hee University.
14장 소켓.
18장 Practical Network Project
제 12장 I/O멀티플렉싱(Multiplexing)
Department of Computer Engineering
Department of Computer Engineering
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
(Web Programming & Practice)
Socket Address Structure and Byte Ordering Functions
Department of Computer Engineering
9장 파일 입출력.
Socket Address Structure and Byte Ordering Functions
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
Chapter 8 연결형 프로토콜 서버 발표자 : SE Lab 황 성 하
Department of Computer Engineering
파일 기술자 복사 파일 기술자 복사 : dup(2) 파일 기술자 복사 : dup2(3)
12장 파일처리와 매크로 파일 입출력 함수 문자 입출력 함수 라인 입출력 함수 불록 입출력 함수 매크로.
Advanced Socket Programming
School of Electronics and Information. Kyung Hee University.
Chapter 4. 보조자료 - 파일 입출력 파일의 기본 개념과 특징을 이해한다. 파일 처리 과정을 이해한다.
C언어 프로그래밍의 이해 Ch14. 파일 입출력.
Department of Computer Engineering
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
Chapter 13 Input/Output and Files
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
소켓의 옵션 School of Electronics and Information. Kyung Hee University.
17강 파일처리함수(1) 강 의 내 용 파일 입출력의 개념 파일포인터를 이용한 입출력 파일 입출력 과정
Linux Programming Spring 2008
멀티 쓰레드 기반의 채팅 프로그램 문성영 김현진 학번 이름 장용하 차희진 연구제안서.
네트워크 프로그래밍의 이해 School of Electronics and Information.
Chapter 16 Socket Interface.
Department of Computer Engineering
Department of Computer Engineering
파일 입출력.
nauten Compiler – Report Ver.3 Mini-C (주간)
Department of Computer Engineering
Homework #7 (1/4) 다음 프로그램을 작성하고, 프로그램과 실행 결과를 함께 제출한다.
Department of Computer Engineering
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
argc, argv 의 사용방법 #include <stdio.h>
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
개정판 누구나 즐기는 C언어 콘서트 제12장 파일 입출력 출처: pixabay.
Department of Computer Engineering
⊙ 입출력 처리란? data를 입력장치로부터 program 내부로 읽어 들이거나
Presentation transcript:

Using Standard I/O on Sockets VLSI 석사 3학기 윤 창 열 한남대학교 컴퓨터공학과 컴퓨터 네트워크 실험실

목차 FILE stream과 소켓 연결하기 읽기 쓰기 FIEL stream의 생성과 적용 소켓과 관련된 stream 닫기 인터럽트 시스템 호출 문제

표준 입출력 필요성 인터페이스의 표준화는 많은 플렛폼에 이식할 수 있도록 한다. stdio(3) package 어플리케이션에서 필요로 하는 기능 제공 read(2), write(2) 등 제공 버퍼링 능력 제공 : 입출력 기능 향상

Stream과 소켓 연결하기 파일 열기 일반적 방법 FILE *in; in = fopen(pathname, "r"); if ( in == NULL ) { fprintf(stderr, "%s : opening %s for read.\n”, strerror(errno), pathename); exit(1); }

소켓과 Stream의 연결을 위한 fdopen 사용 int fildes : 파일 기술자 const char *mode 사용하는 표준 입출력 모드 fopen(3)과 비슷 : “r” – 읽기 “w” – 쓰기 FILE 구조체의 포인터 반환 에러 발생시 외부변수 errno에 원인 포함 #include <stdio.h> FILE *fdopen(int fildes, const char *mode);

소켓과 Stream의 연결을 위한 fdopen 사용 int s; /* 소켓 */ FILE *io; /* 스트림 */ s = socket(PF_INET, SOCK_STREAM, 0); --- io = fdopen(s, "r+"); if ( io == NULL ) { fprintf(stderr, "%s: fdopen(s)", strerror(errno)); exit(1); }

소켓 Stream 닫기 close(s) 사용 안함 fclose(io) stream 변수 io가 사용하는 파일 기술자를 닫음 버퍼링된 데이터가 있다면, write(2) 호출 파일 기술자 닫음 : close(2) 자원 해제 : free(3)

분리된 읽기, 쓰기 Stream의 사용 두개의 분리된 stream을 사용하는 이유 쓰기모드와 읽기 모드의 변환 : fgetpos(3) 적은 오버헤드와 전체적인 버퍼링 기능 향상

분리된 읽기, 쓰기 Stream의 사용 읽기 쓰기 stream의 생성 int s; /* 소켓 */ FILE *rx; /* 읽기 스트림 */ FILE *tx; /* 쓰기 스트림 */ s = socket(PF_INET, SOCK_STREAM, 0); ---

분리된 읽기, 쓰기 Stream의 사용 rx = fdopen(s, "r"); if ( rx == NULL ) { fprintf(stderr, "%s: fdopen(s,'r')", strerror(errno)); exit(1); } tx = fdopen(dup(s), "w"); if ( tx == NULL) { fprintf(stderr, "%s: fdopen(s,'w')", strerror(errno));

소켓의 중첩(duplicating) int dup(int oldfd); 하나의 소켓에 여러 개의 파일 기술자 지정 가능 새로 생성된 파일 기술자도 원래의 소켓을 나타낸다. 생성된 파일 기술자 중 마지막 파일 기술자가 닫혀질 때, 소켓이 닫혀지게 된다.

이중 stream 닫기 버퍼의 상호작용 없앰, fgetpos(3) 필요없음 stream 닫기 rx stream fgets(3), fgetc(3)등 사용 tx stream fputs(3), fputx(3)등 사용 stream 닫기 fclose(rx) : 입력 stream 닫기 fclose(tx) : 출력 stream 닫기

이중 stream 닫기 선행조건 쓰기 stream에 버퍼링된것 버리기 내재하는 파일 기술자 닫기 버퍼 해제 FILE 객체에 의해 제어되는 stream 해제

통신의 종료 shutdown int shutdown(int s, int how) 양방향 통신 연결의 일부를 종료한다. 소켓에 영향을 미치나, 파일 기술자에는 영향을 미치지 않는다.

통신의 종료 쓰는 쪽에서 작업 종료하는 경우 호출하는 프로세스가 더 이상 쓸 데이터가 없음을 커널에 알리기 위해 shutdown(2) 호출 종료 과정 fflush(3)을 이용하여 버퍼안의 데이터 청소 shutdown(2)를 호출하여, 쓰는 측면의 작업 종료 fclose(3)을 이용하여, stream 닫기

통신의 종료 쓰는 쪽의 작업 종료 과정 fflush(tx); shutdown(fileno(tx), SHUT_WR); 쓰기 위한 데이터가 남아있으면 강제적으로 출력 fileno(tx) : tx의 파일 기술자를 반환하는 함수 shutdown( fileno(tx), SHUT_WR) 쓰는 쪽의 작업 중단 fflush(tx); shutdown(fileno(tx), SHUT_WR); fclose(tx);

통신의 종료 읽는 쪽에서 작업 종료하는 경우 더 이상 받을 데이터가 없음을 표시하기 위해 shutdown(2) 호출 fclose 함수 이용해 stream 닫기 Fflush(3) 호출의 불필요 shutdown(fileno(rx), SHUT_RD); fclose(rx);

통신의 종료 읽기, 쓰기 모두에서 작업 종료 종료 과정 fclose 호출을 통해 tx, rx 모두 종료 rx를 닫을 때 stream 닫는다. 종료 과정 fclose(3) 을 이용하여 쓰기 stream 닫기 쓰여지지 않은 데이터 강제적 출력 자원 해제 읽기 쓰기 종료를 위한 shutdown(2) 호출 fclose(3) 을 이용하여 읽기 stream 닫기 stream 버퍼와 FILE 구조체 해제

통신의 종료 fclose(tx); shutdown(fileno(rx), SHUT_RDWR); fclose(rx); 다른 프로세스의 영향에도 안정적 수행

인터럽트 처리 EINTR 에러 메시지 EINTR 메시지를 숨기는 경향 인터럽트 시스템 호출이 발생했음을 나타냄 함수 호출이 오랫동안 대기 상태일 때 메시지 출력 EINTR 메시지를 숨기는 경향 다른 플렛폼(unix 등)으로 이식이 필요할 경우 이 메시지 제어 필요

인터럽트 처리 EINTR 메시지의 허용을 위한 코드 int ch; do clearerr(rx); Clearerr(rx) : rx stream의 에러 지우기 ferror(rx) : rx stream에 에러가 있는지 테스트 int ch; do clearerr(rx); ch = fgets(rx); /* 입출력 동작 수행 */ while ( ferror(rx) && errno == EINTR);

인터럽트 처리 EINTR을 제어할 필요가 있을 때 Gnu C 라이브러리는 EINTR 에러를 숨기는 방향으로 변함 리눅스에서 다른 유닉스 플렛폼에 이식해야 할 경우 어플리케이션에서 EINTR 에러가 가끔씩 발생하는 경우 Gnu C 라이브러리는 EINTR 에러를 숨기는 방향으로 변함

인터럽트 처리 Connect(2) writev(2) Accept(2) recvfrom(2) Read(2) sendto(2) 다른 기능을 위한 EINTR 제어 인터럽트에 의해서 영향 받는 함수 Connect(2) writev(2) Accept(2) recvfrom(2) Read(2) sendto(2) Write(2) select(2) Readv(2) poll(2)

버퍼 동작 정의 stdio(3)을 사용하면 내부 버퍼 사용 버퍼의 사용은 시스템 효율성 증가 읽기, 쓰기 모두 적용 버퍼링의 세가지 모델 Fully buffered( or “block” buffered) Line buffered Unbuffered

버퍼 동작 정의 Unbuffered Line buffered Fully buffered 버퍼링의 효율성이 없을때 버퍼를 사용하지 않을 수 있다. Line buffered 텍스트 라인 기반의 동작에 유용 Fully buffered 물리적으로 쓰기 원하는 지점에서 fflush(3) 적용 데이터가 출력되지 않기 때문에, 어플리케이션이 데이터를 기다리는 경우가 발생

버퍼 동작 정의 버퍼 함수의 개략적 정의 #include <stdio.h> int setbuf(FILE *stream, char *buf); 열린 stream의 버퍼 모드를 변경한다. int setbuffer(FILE *stream, char *buf, size_t size); int setlinebuf(FILE *stream); int setvbuf(FILE *stream, char *buf, int mode, size_t size);

버퍼 동작 정의 전달 인수 설명 버퍼링 모드 *stream은 영향을 받는 FILE의 포인터이다. *buf 포인터는 제공되어지는 버퍼의 포인터이다. size 인수는 버퍼의 바이트 사이즈 의미 mode 인수는 버퍼링 모드를 나타낸다. 버퍼링 모드 _IOFBF : fully buffered _IOLBF : line buffered _IONBF : 버퍼링 하지 않음

소켓에 FILE stream 적용하기 계산기 Mkaddr() 함수 임의의 긴 정수를 수용 스택에 저장 후 계산 Gnu Multi-Precision(GMP) 라이브러리 이용 Mkaddr() 함수 Int mkaddr(void *addr, int *addr_lin, char *str_addr, char *protocol); Return value 0 : 성공적 수행 -1 : 문자열의 호스트 부분의 이상, unknown host name -2 : 포트 넘버가 틀렸거나, 알려지지 않은 서비스 이름

소켓에 FILE stream 적용하기 mkaddr() 함수의 인수 addr : 소켓 구조를 받는 주소 addr_len : 주소의 길이를 나타내는 정수의 포인트 str_addr : 상징적인 호스트네임과 선택적인 포트 넘버 host_name : service 의 구조 Host_name => 127.0.0.1 or sunsite.unc.edu Service => 8080 or telnet protocol : 서버가 사용하는 프로토콜, 널 포인터는 문자열 “tcp”를 나타낸다.

Mkaddr 함수 flow 호스트 부분과 포트 부분의 default value 설정 Address 구조의 초기화 호스트 주소 채우기 포트 넘버 채우기 종 료

Mkaddr.c char *inp_addr = strdup(str_addr); Strdup 함수를 이용한 string 중첩하기 char *host_part = strtok(inp_addr,":"); Strtok 함수를 이용하여 호스트 스트링 추출하기 char *port_part = strtok(NULL,""); Strtok 함수를 이용하여 포트 스트링 추출하기 memset(ap, 0, *addrlen) addreln 크기의 바이트에 ap 주소에서 부터 0으로 채우는 함수

RPN 계산기 엔진 코드 rpn_dump(tx) rpn_process(FILE *tx, char *buf) Stack에 있는 내용 출력 rpn_process(FILE *tx, char *buf) buf의 내용이 dump이면 rpn_dump(tx) 실행 buf의 내용이 ‘=‘이면, 결과 출력 buf의 내용이 ‘#’이면, 스택에 넣기 그 밖의 내용이면 버퍼 내용에 따른 동작 rpn_opr(operation) 실행

rpnsrv.c : 계산기 동작을 위한 메인 함수 Stream 생성 서버의 주소가 인수로 주어 졌는지 파악 생성된 두개의 stream을 Buffered mode로 설정 서버의 주소를 구성하기 위해 mkaddr() 호출 클라이언트 요구 처리 사용할 TCP/IP 소켓 생성 클라이언트 연결 해제 서버 주소 결합 종 료 서버 시작

len_inet = sizeof adr_srvr; z = mkaddr(&adr_srvr,&len_inet, 서버의 주소가 인수로 주어 졌는지 파악 if ( argc >= 2 ) srvr_addr = argv[1]; 서버의 주소를 구성하기 위해 mkaddr() 호출 len_inet = sizeof adr_srvr; z = mkaddr(&adr_srvr,&len_inet, srvr_addr,"tcp"); if ( z < 0 || !adr_srvr.sin_port ) fprintf(stderr,"Invalid server " "address, or no port number " "was specified."); exit(1); }

z = listen(s,10); s = socket(PF_INET,SOCK_STREAM,0); if ( s == -1 ) 사용할 TCP/IP 소켓 생성 s = socket(PF_INET,SOCK_STREAM,0); if ( s == -1 ) bail("socket(2)"); 서버 주소 결합 z = bind(s,(struct sockaddr *)&adr_srvr, len_inet); if ( z == -1 ) bail("bind(2)"); 서버 시작 z = listen(s,10); if ( z == -1 ) bail("listen(2)");

for (;;) /* * Wait for a connect : */ len_inet = sizeof adr_clnt; 서버 시작 - 연결 대기 for (;;) /* * Wait for a connect : */ len_inet = sizeof adr_clnt; c = accept(s, (struct sockaddr * )&adr_clnt, &len_inet); if ( c == -1 ) bail("accept(2)"); Stream 생성 rx = fdopen(c,"r"); if ( !rx ) /* Failed */ close(c); continue; } tx = fdopen( dup(c),“w"); if ( !tx ) fclose(rx); continue; }

while ( fgets(buf,sizeof buf,rx) ) rpn_process(tx,buf); 생성된 두개의 stream을 Buffered mode로 설정 setlinebuf(rx); setlinebuf(tx); 클라이언트 요구 처리 while ( fgets(buf,sizeof buf,rx) ) rpn_process(tx,buf); 클라이언트 연결 해제 fclose(tx); shutdown(fileno(rx),SHUT_RDWR); fclose(rx); 종 료

실행 결과 $ ./rpnsrv & #:970976453 0: [1] 13321 $ telnet localhost 9090 trying 127.0.0.1... Connected to localhost. Escape character is '^]' #:970976453 0: #:2636364 1: dump 1:2636364 0:970976453 E:end of stack dump

실행 결과 : 덧셈예제 $telnet localhost 9090 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. #:970976453 0: #:2636364 1: + 0: = 0:973612817 ^] telnet> c Connection closed. $

요약 FILE stream과 소켓 연결하기 읽기 쓰기 FIEL stream의 생성과 적용 소켓과 관련된 stream 닫기 io = fdopen(s, "r+"); 읽기 쓰기 FIEL stream의 생성과 적용 읽기, 쓰기 stream의 따로 생성 소켓과 관련된 stream 닫기 버퍼링 방식 선택 인터럽트 시스템 호출 문제 다른 플렛폼의 이식성을 위해서 필요 : EINTR 에러 메시지