데이터 통신
두개의 직접 연결된 디바이스가 데이터를 교환하는 것
채널 개수로 구분
데이터는 비트의 형태로 디바이스 사이를 이동한다.
- 직렬 통신 (Serial Transmission)
- 병렬 통신 (Parallel Transmission)
직렬 통신 (Serial Transmission)
한개의 채널을 사용해 한 비트씩 순서대로 이동시키는 방식
비동기 직렬 통신 (Asynchronous Serial Transmission)
데이터 비트가 언제든지 전송될 수 있다.
start bits와 stop bits가 데이터 바이트의 양 끝에 함께 보내져서 수신이 제대로 이루어졌음을 보장해준다.
데이터 비트를 주고받는 시간은 일정하지 않다. → 전송 시간 사이에 gaps가 사용된다.
- 원리
- 통신을 하지 않는동안은 통신회선이 항상 1로 유지된다.
- 시작비트인 0이 들어와 회선의 상태가 변하면 데이터를 수신하기 시작한다.
- 8비트를 모두 수신하면 정지비트를 수신하고 통신을 종료한다.
- 장점
- 송수신자 사이에 동기화가 필요 없다.
- 비용 효율이 높다.
- 단점
- 전송 속도가 느려질 수 있다.(항상 그런 것은 아님)
동기 직렬 통신 (synchronous Serial Transmission)
master의 clock신호에 맞춰서 연속적으로 데이터 비트가 이동한다.
송수신자는 동기화된 clock을 사용한다. → start bits, stop bits, gaps가 필요없다.
- 동기화 : 송수신자간의 신호의 타이밍을 맞추어 정확한 송수신이 가능하도록 하는 것
- 장점
- 데이터 전송 속도가 빠르고 타이밍 에러가 적게 발생한다.
- 단점
- 데이터의 정확도가 동기화 정도의 영향을 받는다.
- 비용 효율이 낮다.
사용되는 곳
- 장거리 데이터 통신
- 데이터의 양이 상대적으로 적은 경우
- 데이터의 무결성(변경 및 파괴되지 않은 상태)을 보장한다.
병렬 통신 (Parallel Transmission)
다중 채널을 사용해 여러 데이터 비트를 한번에 이동시키는 방식
장단점
- 장점
- 프로그래밍하기 쉬움
- 데이터 전송 속도가 빠름
- 단점
- 여러 채널을 사용하기 때문에 싱크가 안맞을 수 있다.
사용되는 곳
- 데이터의 양이 많은 경우
- 시급한 데이터인 경우
- 예시) 비디오 스트리밍
통신 방향으로 구분
단방향 (Simplex) | 반이중 (Half Duplex) | 전이중 (Full Duplex) | |
---|---|---|---|
통신방향 | 단방향 (Unidirectional) | 쌍방향 (Two-directional, One by one) | 양방향 (Bi-directional, Simultaneously) |
Sender의 동작 | Sender는 데이터만 전송할 수 있다. | Sender는 데이터를 하나씩 주고받을 수 있다. | Sender는 데이터를 동시에 주고받을 수 있다. |
성능 | 나쁨 | 보통 | 좋음 |
sigaction
sigaction 함수
int sigaction(int sig, const struct sigaction *restrict act, struct sigaction *restrict oact);
signal 함수보다 다양한 기능을 지원하는 함수
- 헤더 : signal.h
- 매개변수
- sig : 시그널 번호
- act : 새롭게 설정할 행동
- oact : 이전에 지정했던 행동
- 반환값
- 0 : 성공
- -1 : 실패
sigaction 구조체
1
2
3
4
5
6
7
8
9
10
struct sigaction {
union __sigaction_u __sigaction_u; // 시그널 핸들러
sigset_t sa_mask; // 시그널을 처리하는 동안 블록화할 시그널 집합의 마스크
int sa_flags; // 아래 설명 참고
};
union __sigaction_u {
void (*__sa_handler)(int); // 시그널을 처리할 핸들러
void (*__sa_sigaction)(int, siginfo_t *, void *); // sa_handler 대신에 동작할 핸들러
};
sigaction 함수를 사용하기 위해 해당 구조체를 선언해야한다.
sa_handler, sa_sigaction
두 멤버 모두 시그널이 들어왔을 때 해당 시그널을 처리할 핸들러를 지정
sa_flags = SA_SIGINFO
일 경우 sa_handler 대신 sa_sigaction이 동작한다.
sa_mask
핸들러의 동작 중 처리를 블록할 signal_set을 지정한다.
sa_flags
다양한 옵션을 통해 sigaction의 핸들러가 동작하는 방식을 관리한다.
flag는 signal.h
에 위와 같이 정의되어있다.
옵션 | 의미 |
---|---|
SA_NOCLDSTOP | signum이 SIGCHILD일 경우, 자식 프로세스가 멈추었을 때, 부모 프로세스에 SIGCHILD가 전달되지 않는다. |
SA_ONESHOT | 시그널을 받으면 설정된 행도을 취하고 시스템 기본 설정인 SIG_DFL로 재설정된다. |
SA_RESETHAND | 위와 동일 |
SA_RESTART | 시그널 처리에 의해 방해 받은 시스템 호출은 시그널 처리가 끝나면 재시작한다. |
SA_NOMASK | 시그널을 처리하는 동안에 전달되는 시그널은 블록되지 않는다. |
SA_NODEFER | 위와 동일 |
SA_SIGINFO | 이 옵션이 사용되면 sa_handler대신에 sa_sigaction이 동작되며, sa_handler 보다 더 다양한 인수를 받을 수 있다. sa_sigaction이 받는 인수에는 시그널 번호, 시그널이 만들어진 이유, 시그널을 받는 프로세스의 정보가 있다. |
test_sigaction.sa_flags = SA_SIGINFO | SA_NODEFER;
위와 같이 비트 OR 연산자를 사용해 여러가지 flag를 적용할 수 있다.
exit 함수
void exit(int status);
- 아래의 작업을 거친 후 프로세스를 종료시킴
- atexit(3) 함수에 등록된 함수를 등록된 역순으로 호출한다.
- 열려 있는 모든 출력 스트림을 flush(버퍼를 비우는 것)한다.
- 열려 있는 스트림을 모두 닫는다.
- tmpfile(3) 함수로 작성된 모든 파일의 연결을 해제한다.
- 인자로 받은 status는 운영체제에 전달한다.
- 0 : 정상 종료, 0 이외의 값 : 에러 발생
return과의 차이
- return은 함수를 종료하는 키워드
- exit은 프로그램을 종료하는 함수
- main문에서의 동작은 동일하지만 다른 함수에서는 동작이 다름
Unicode
전 세계의 모든 문자를 컴퓨터에서 일관되게 다룰 수 있도록 설계된 산업 표준
매핑 방식
- 유니코드 변환 형식 (Unicode Transformation Format, UTF) 인코딩
- UTF-1
- UTF-7
- UTF-8
- UTF-EBCDIC
- UTF-16
- UTF-32
- 국제 문자 세트 (Universal Coded Character Set, UCS) 인코딩
UTF-8 (Unicode)
유니코드를 위한 가변 길이 문자 인코딩 방식
인코딩
유니코드 한 문자를 나타내기 위해 1 ~ 4 바이트를 사용한다. 사용할 바이트는 코드의 범위에 따라 다름(하단 표 참고).
설계 원칙
- 1바이트로 표시된 문자의 최상위 비트는 항상 0이다.
- 2바이트 이상으로 표시된 문자의 경우, 첫 바이트의 상위 비트들이 그 문자를 표시하는 데 필요한 바이트 수를 결정한다. 예를 들어서 2바이트는 110으로 시작하고, 3바이트는 1110으로 시작한다.
- 첫 바이트가 아닌 나머지 바이트들은 상위 2비트가 항상 10이다.
Ref.
https://www.quantil.com/content-delivery-insights/content-acceleration/data-transmission/
https://m.blog.naver.com/cjsksk3113/222009286458
https://codingdog.tistory.com/entry/c언어-signal-함수-선언부를-해석해-봅시다
https://badayak.com/entry/C언어-시그널-처리-함수-sigaction
https://ko.wikipedia.org/wiki/UTF-8
https://en.wikipedia.org/wiki/UTF-8