Part 1. Linux 환경
Ch. 1. Socket Network Programming
Ch. 5. Network Byte Order, Big Endian, Little Endian
Part 2. Window 환경
Ch.10.
Ch.11.
Ch.12.
Ch.13.
Ch.14.
Ch.15.
Ch.16.
Ch.17.
Ch.18.
파일 디스크립터(File Descriptor)
리눅스에서 파일 디스크립터란, C 언어와 같은 프로그래밍 언어가 아닌 시스템(OS)에 의해 관리되는 일련의 정수값으로 파일 또는 소켓의 식별에 사용된다.
윈도우는 파일과 소켓을 구분한다.
▶ UNIX에서 파일을 새로 열면(open) int 타입의 정수를 리턴하는데, 이는 파일 기술자 테이블(file descriptor table) 의 index 번호다.
▶ 예를들어, 2개의 파일을 open하면 파일 기술자는 3과 4가 배정되며, 소켓을 생성하면 파일 기술자와 똑같은 기능과 역할을 하는 소켓 기술자(socket descriptor)가 리턴된다. 즉, 파일과 소켓이 기술자 테이블을 공유한다.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
int main(void)
{
int fd1, fd2, fd3;
fd1=socket(PF_INET, SOCK_STREAM, 0);
fd2=open("test.dat", O_CREAT|O_WRONLY|O_TRUNC);
fd3=socket(PF_INET, SOCK_DGRAM, 0);
printf("file descriptor 1: %d\n", fd1); // file descriptor 1: 3
printf("file descriptor 2: %d\n", fd2); // file descriptor 1: 4
printf("file descriptor 3: %d\n", fd3); // file descriptor 1: 5
// 3 부터 시작하는 이유는 0,1,2 는 표준 입출력에 할당되었기 때문이다.
close(fd1);
close(fd2);
close(fd3);
return 0;
}
파일 열기
#include <fcntl.h>
int open(const char *path, int flag);
// 성공 시 파일 디스크립터, 실패시 -1 반환
// path : 파일 주소
// plag : 파일의 오픈 모드 옵션
파일 닫기
#include <unistd.h>
int close(int fd);
//성공시 0, 실패시 -1 반환
//fd : 닫고자 하는 파일 또는 소켓의 파일 디스크립터 전달
파일은 사용 후 반드시 닫아야한다.
파일에 데이터 쓰기 (데이터 전송하기)
리눅스에서는 파일과 소켓을 동일하게 취급하므로 소켓을 통해서 다른 컴퓨터에 데이터를 전송할 때에도 write 함수를 사용할 수 있다.
write 반환 시점은 데이터가 전송되는 순간이 아니라, 출력 버퍼로 이동 완료되는 순간이다.
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes);
// 성공시 전달한 바이트 수, 실패시 -1 반환
// fd : 데이터 전송대상을 나타내는 파일 디스크립터 전달.
// buf : 전송할 데이터가 저장된 버퍼의 주소 값 전달.
// nbytes : 전송할 데이터의 바이트 수 전달.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void error_handling(char* message);
int main(void)
{
int fd;
char buf[]="Let's go!\n";
fd=open("data.txt", O_CREAT|O_WRONLY|O_TRUNC);
if(fd==-1)
error_handling("open() error!");
printf("file descriptor: %d \n", fd);
if(write(fd, buf, sizeof(buf))==-1)
error_handling("write() error!");
close(fd);
return 0;
}
void error_handling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
파일에 데이터 읽기 (데이터 전송받기)
데이터를 입력(수신, 전송받는)하는 기능의 함수이다.
read 함수가 호출되는 순간 입력 버퍼에 저장된 데이터를 읽어 들인다.
#include <unistd.h>
ssize_t read(int fd , void *buf , size_t nbytes);
// 성공시 수신한 바이트 수 (단 파일의 물을 만나면 0), 실패시 -1 반환
// fd : 데이터 대상을 나타내는 파일 디스크립터 전달
// buf : 수신한 데이터를 저장할 버퍼의 주소 값 전달
// nbytes : 수신할 최대 바이트 수 전달
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUF_SIZE 100
void error_handling(char* message);
int main(void)
{
int fd;
char buf[BUF_SIZE];
fd=open("data.txt", O_RDONLY);
if( fd==-1)
error_handling("open() error!");
printf("file descriptor: %d \n" , fd);
if(read(fd, buf, sizeof(buf))==-1)
error_handling("read() error!");
printf("file data: %s", buf);
close(fd);
return 0;
}
void error_handling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
출처 & 참고
Part 1. Linux 환경
Ch. 1. Socket Network Programming
Ch. 5. Network Byte Order, Big Endian, Little Endian
Part 2. Window 환경
Ch.10.
Ch.11.
Ch.12.
Ch.13.
Ch.14.
Ch.15.
Ch.16.
Ch.17.
Ch.18.
파일 디스크립터(File Descriptor)
리눅스에서 파일 디스크립터란, C 언어와 같은 프로그래밍 언어가 아닌 시스템(OS)에 의해 관리되는 일련의 정수값으로 파일 또는 소켓의 식별에 사용된다.
윈도우는 파일과 소켓을 구분한다.
▶ UNIX에서 파일을 새로 열면(open) int 타입의 정수를 리턴하는데, 이는 파일 기술자 테이블(file descriptor table) 의 index 번호다.
▶ 예를들어, 2개의 파일을 open하면 파일 기술자는 3과 4가 배정되며, 소켓을 생성하면 파일 기술자와 똑같은 기능과 역할을 하는 소켓 기술자(socket descriptor)가 리턴된다. 즉, 파일과 소켓이 기술자 테이블을 공유한다.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
int main(void)
{
int fd1, fd2, fd3;
fd1=socket(PF_INET, SOCK_STREAM, 0);
fd2=open("test.dat", O_CREAT|O_WRONLY|O_TRUNC);
fd3=socket(PF_INET, SOCK_DGRAM, 0);
printf("file descriptor 1: %d\n", fd1); // file descriptor 1: 3
printf("file descriptor 2: %d\n", fd2); // file descriptor 1: 4
printf("file descriptor 3: %d\n", fd3); // file descriptor 1: 5
// 3 부터 시작하는 이유는 0,1,2 는 표준 입출력에 할당되었기 때문이다.
close(fd1);
close(fd2);
close(fd3);
return 0;
}
파일 열기
#include <fcntl.h>
int open(const char *path, int flag);
// 성공 시 파일 디스크립터, 실패시 -1 반환
// path : 파일 주소
// plag : 파일의 오픈 모드 옵션
파일 닫기
#include <unistd.h>
int close(int fd);
//성공시 0, 실패시 -1 반환
//fd : 닫고자 하는 파일 또는 소켓의 파일 디스크립터 전달
파일은 사용 후 반드시 닫아야한다.
파일에 데이터 쓰기 (데이터 전송하기)
리눅스에서는 파일과 소켓을 동일하게 취급하므로 소켓을 통해서 다른 컴퓨터에 데이터를 전송할 때에도 write 함수를 사용할 수 있다.
write 반환 시점은 데이터가 전송되는 순간이 아니라, 출력 버퍼로 이동 완료되는 순간이다.
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes);
// 성공시 전달한 바이트 수, 실패시 -1 반환
// fd : 데이터 전송대상을 나타내는 파일 디스크립터 전달.
// buf : 전송할 데이터가 저장된 버퍼의 주소 값 전달.
// nbytes : 전송할 데이터의 바이트 수 전달.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void error_handling(char* message);
int main(void)
{
int fd;
char buf[]="Let's go!\n";
fd=open("data.txt", O_CREAT|O_WRONLY|O_TRUNC);
if(fd==-1)
error_handling("open() error!");
printf("file descriptor: %d \n", fd);
if(write(fd, buf, sizeof(buf))==-1)
error_handling("write() error!");
close(fd);
return 0;
}
void error_handling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
파일에 데이터 읽기 (데이터 전송받기)
데이터를 입력(수신, 전송받는)하는 기능의 함수이다.
read 함수가 호출되는 순간 입력 버퍼에 저장된 데이터를 읽어 들인다.
#include <unistd.h>
ssize_t read(int fd , void *buf , size_t nbytes);
// 성공시 수신한 바이트 수 (단 파일의 물을 만나면 0), 실패시 -1 반환
// fd : 데이터 대상을 나타내는 파일 디스크립터 전달
// buf : 수신한 데이터를 저장할 버퍼의 주소 값 전달
// nbytes : 수신할 최대 바이트 수 전달
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUF_SIZE 100
void error_handling(char* message);
int main(void)
{
int fd;
char buf[BUF_SIZE];
fd=open("data.txt", O_RDONLY);
if( fd==-1)
error_handling("open() error!");
printf("file descriptor: %d \n" , fd);
if(read(fd, buf, sizeof(buf))==-1)
error_handling("read() error!");
printf("file data: %s", buf);
close(fd);
return 0;
}
void error_handling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
출처 & 참고