- 리눅스 vs. 윈도우
: 편견을 갖을 필요 없다. 각각의 장단점이 있다.
: 시스템콜 기반과 표준라이브러리 IO와 차이
: 시스템콜 메커니즘 자체는 리눅스와 윈도우가 같다.
: 리눅스는 무료 오픈소스로 파일 디스크립터, 오픈파일 등의 세팅을 바꾸어줄수 있지만 윈도우즈는 변경하기가 힘들고, 가격이 비싸지만 (windows server 같은 경우 cpu당 라이센스 비용 지불), 개발이 쉽다.
: 바로 함수를 호출하는 메커니즘 vs 하나를 거쳐 호출하는 메커니즘
: mono vs micro
: 커널을 다시 빌드해야함 vs 모듈처럼 사용 가능하지만 성능 저하
: android 코드를 분석해보면 bionic -> 각각의 CPU에 대해 존재하는 이유는 시스템콜 때문이다. 시스템 콜
12345678910111213141516171819202122232425262728293031323334#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h >
// stdin, stdout, stderr : FILE*
// STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO : int
// task_struct
// 1. socket programming 저수준 IO를 사용합니다.
// 2. 저수준 IO : 운영체제에서 제공하는 IO 관련 API
// Windows : Win32/64 API
// Linux : System Call
// 3. 프로세스를 통해 파일을 관리한다.
// ulimit -a
int
main()
{
// FILE* fp = fopen("sample", "r");
int
fd = open(
"sample"
, O_RDONLY);
printf
(
"fd : %d\n"
, STDIN_FILENO);
printf
(
"fd : %d\n"
, STDOUT_FILENO);
printf
(
"fd : %d\n"
, STDERR_FILENO);
printf
(
"fd : %d\n"
, fd);
// fd 출력시 3인 이유는 표준 입출력, 에러에 대한 fd가 열려있기 때문이다
// VFS라고 부른다 -> 다형성
// 내부적으로 파일, 디바이스를 다루는 모든 방식은 파일로 되어있다. 이를 사용하기 위해서는 각각을 모두 열어야한다. -> 동적바인딩을 통해서
// 리눅스는 array로 파일디스크립터 관리, 윈도우즈는 파일디스크립터 핸들
}
∴버퍼링 정책 3가지
1. Full Buffering : Buffer가 가득 차면 화면에 출력 → File I/O
2. Line Buffering : ‘\n’이 오면 화면에 출력 → printf의 경우에 해당
3. Non Bufering : 버퍼링을 하지 않음. → fprintf(stderr,””);에 해당pirntf("error");
while(1);
//출력하지 않는다.
pirntf("error\n");
while(1);
//출력한다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int
main()
{
int
fd = open(
"sample"
, O_RDONLY);
printf
(
"fd : %d\n"
, fd);
// 문제점
// 1. 에러 발생시 -1 리턴
// 2. 버퍼의 크기가 너무 작을 경우, 빈번한 컨텍스트 스위칭으로 인한
// 성능 저하가 있다.
#if 0
char
ch;
while
(read(fd, &ch,
sizeof
ch) > 0)
putchar
(ch);
#endif
// 3. read(fd, buf, size)
// size : 버퍼의 최대 크기
// 4. write(fd, buf, size)
// size : 쓰고자 하는 데이터의 실제 양
char
buf[128];
int
ret;
while
((ret = read(fd, buf,
sizeof
buf)) > 0) {
write(1, buf, ret);
// buf[ret] = '\0';
// printf("%s", buf);
}
close(fd);
// close를 안해도 문제가 없었던 이유
// 프로세스가 종료되면서 소유하고 있던 자원을 모두 해지
// app영역에서는 프로세스 종료로 OS가 메모리를 수거함. 대부분 커널의 누수
// 정적분석은 new와 delete쌍을 찾아서 싱글톤은 메모리 누수로 인식함
// 동적분석은 비쌈
}
클라이언트 작성하기
- http 통신123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
int
main()
{
// 1. 소켓 생성 : socket()
int
sd = socket(PF_INET,
// 프로토콜
SOCK_STREAM,
// TCP(SOCK_STREAM), UDP(SOCK_DGRAM)
IPPROTO_TCP);
// 하위 프로토콜(생략, 0 으로 지정 가능)
// 2. 서버 주소 지정 : 초기화 이전에 0으로 초기화해야 한다.
// 문자열 ip -> 32 bit : inet_addr
struct
sockaddr_in addr = {0, };
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = inet_addr(
"127.0.0.1"
);
// 3. 접속 수행
int
ret = connect(sd, (
struct
sockaddr*)&addr,
sizeof
(addr));
if
(ret == -1) {
// 에러 처리 방법 3가지
// 1. printf("connect() error : %d\n", errno);
// 2. char* msg = strerror(errno);
// printf("connect() error : %s\n", msg);
// 3.
perror
(
"connect()"
);
goto
err;
}
{
printf
(
"Connection succeed!!\n"
);
// "GET \n\n"
char
buf[1024] =
"GET /\n\n"
;
write(sd, buf,
strlen
(buf));
int
len;
while
((len = read(sd, buf,
sizeof
(buf))) > 0) {
write(1, buf, len);
}
}
err:
// 4. 접속 종료
close(sd);
}
- DNS123456789101112131415161718192021222324252627282930#include <stdio.h>
// domain -> ip address
// : gethostbyname
// gethostbyname
#include <netdb.h>
// inet_ntoa: 네트워크로부터 온 패킷을 아스키코드로 바꾸어 주는 것
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int
main()
{
struct
hostent* host = gethostbyname(
"www.google.com"
);
// name
printf
(
"host name : %s\n"
, host->h_name);
// alias
for
(
int
i = 0 ; host->h_aliases[i] ; i++) {
printf
(
"Alias[%d] : %s\n"
, i + 1, host->h_aliases[i]);
}
for
(
int
i = 0 ; host->h_addr_list[i] ; i++) {
printf
(
"Address[%d] : %s\n"
,
i+1,
inet_ntoa(*(
struct
in_addr*)host->h_addr_list[i]) );
}
}
'Programing > Server Model' 카테고리의 다른 글
서버 모델 - I/O 모델 개요 (0) | 2016.02.22 |
---|---|
서버 모델 - 리눅스 소켓 프로그래밍(3) (0) | 2016.02.22 |
서버 모델 - 리눅스 소켓 프로그래밍(2) (0) | 2016.02.18 |
서버 모델 - 리눅스 소켓 프로그래밍(1) (0) | 2016.02.18 |
서버 모델 - 기초 (0) | 2016.02.16 |