pdcomm::TcpEndpoint
클래스
TCP/IP 위의 HSMS(SEMI E37) 끝점(endpoint) 하나를 소유하는 이동 전용 객체입니다.
class TcpEndpoint끝점은 HSMS 연결 역할(role) 하나입니다. 능동(active) 끝점은 상대에 연결하고, 연결할 때마다 Select.req를 보냅니다. 수동(passive) 끝점은 연결을 기다리고, 한 번에 연결 하나를 수락하며, 상대의 Select.req에 응답합니다. 끝점은 스레드를 시작하지 않고, 콜백을 호출하지 않으며, 호스트 이름을 해석하지 않습니다. 호출자의 루프에서 다음과 같이 구동합니다.
- 숫자 주소와 값을 채운
PdcommTcpOptions로 생성합니다. 수동 끝점은 생성 중에 수신 대기 소켓을 바인딩합니다. - start()를 호출해 첫 연결 세대(generation)를 시작합니다.
- poll()을 반복 호출해 소켓 I/O를 수행하고 HSMS 타이머를 실행한 뒤, nextEvent()가 빈 이벤트를 반환할 때까지 이벤트를 꺼냅니다.
- SELECTED 상태에서 request()로 1차 메시지를 보내고, 수신한 1차 메시지 중 W 비트가 설정된 메시지에는 reply()로 응답합니다.
- 정상 종료하려면 stop()을 호출하고,
state().closed가 1이 될 때까지 계속 폴링하며 이벤트를 꺼낸 뒤 끝점을 파괴합니다.
연결을 시도할 때마다 새 세대가 시작됩니다. 제출할 때마다 끝점 식별자, 세대, HSMS 시스템 바이트(system bytes)를 담은 PdcommTcpToken을 반환합니다. 다른 끝점이나 이전 세대의 토큰 또는 이벤트는 만료된(stale) 것입니다. 제출이 성공했다는 것은 메시지가 큐에 들어갔다는 뜻일 뿐입니다. 응답, 타임아웃, 실패는 나중에 이벤트로 도착합니다.
빈 끝점(기본 생성되었거나 이동된 끝점)에 대한 모든 호출은 PDCOMM_INVALID_ARGUMENT와 함께 pdcomm::Error를 던집니다. 내부 패닉이 발생한 뒤에는 모든 호출이 PDCOMM_POISONED로 예외를 던지며, 파괴만 의미가 있습니다. nextEvent()가 이벤트를 할당하지 못하면 이벤트는 끝점 안에 보류(staged)됩니다. nextEvent()가 그 이벤트를 반환할 때까지 start(), stop(), poll(), 제출 호출, cancel()은 PDCOMM_BACKPRESSURE로 예외를 던집니다.
GemHost와 GemEquipment는 TcpEndpoint를 소유합니다. GemEndpoint::tcp()로 접근하고, nextEvent()에서 받은 모든 이벤트를 큐 순서대로 GemEndpoint::handleEvent()에 전달합니다.
아래 예제는 W 비트가 설정된 수신 1차 메시지마다 SxF0 중단(abort) 응답을 보냅니다.
pdcomm::TcpEndpoint endpoint("127.0.0.1:5000", options);
endpoint.start();
while (running) {
endpoint.poll();
while (auto event = endpoint.nextEvent()) {
const auto info = event.info();
if (info.kind == PDCOMM_TCP_RECEIVED && !info.is_reply && info.reply_expected) {
endpoint.reply(event, info.stream, 0, false, nullptr, 0);
}
}
}
endpoint.stop();
while (!endpoint.state().closed) {
endpoint.poll();
while (endpoint.nextEvent()) {}
}참고
- 이동 전용입니다. 끝점은 내부에서 동기화되지 않습니다. 게터, 같은 끝점에 대한 GEM 호출, 파괴를 포함해 이 끝점에 대한 모든 호출을 직렬화해야 합니다. 진행 중인 호출이 없는 끝점은 다른 스레드로 옮길 수 있습니다. 문자열이나 벡터를 만드는 호출은
std::bad_alloc도 던질 수 있습니다.
멤버
TcpEndpoint
생성자
네이티브 핸들을 소유하지 않는 빈 끝점을 만듭니다.
TcpEndpoint() noexcept = default빈 끝점에 대한 모든 호출은 PDCOMM_INVALID_ARGUMENT와 함께 pdcomm::Error를 던집니다. 사용하기 전에 생성된 끝점을 이 객체로 이동해야 합니다.
TcpEndpoint
생성자
other가 소유한 네이티브 핸들의 소유권을 가져옵니다.
TcpEndpoint(TcpEndpoint &&other) noexcept네이티브 끝점은 식별자와 세대를 유지하므로, 기존 토큰과 이벤트는 이 래퍼에서도 계속 유효합니다.
매개변수
| 이름 | 설명 |
|---|---|
other | 원본 래퍼입니다. 호출 후 비게 됩니다. |
TcpEndpoint
생성자
복사할 수 없습니다. 래퍼가 네이티브 핸들을 단독으로 소유합니다.
TcpEndpoint(const TcpEndpoint &) = deleteTcpEndpoint
생성자
pdcomm_tcp_create()로 HSMS 끝점을 만듭니다.
TcpEndpoint(const char *address, size_t addressLength, const PdcommTcpOptions &options)주소와 옵션을 검증한 뒤 복사합니다. 수동 끝점은 이 호출 중에 수신 대기 소켓을 바인딩합니다. 능동 끝점은 poll()이 연결 시도를 실행할 때까지 I/O를 수행하지 않습니다. 새 끝점은 정지 상태이므로 start()를 호출해 시작합니다.
매개변수
| 이름 | 설명 |
|---|---|
address | NUL 종료 문자가 없는 UTF-8 텍스트로 된 숫자 소켓 주소입니다. 예: 127.0.0.1:5000, [::1]:5000. 호스트 이름은 해석하지 않습니다. 능동 모드에서는 상대 주소이고, 수동 모드에서는 로컬 수신 대기 주소입니다. 수동 모드에서 포트 0을 지정하면 소켓을 바인딩할 때마다 임시 포트를 선택합니다(localAddress()로 확인합니다). |
addressLength | address의 바이트 수입니다. |
options | 끝점 구성입니다. 모든 타이머와 한도는 애플리케이션 정책입니다. PDComm은 기본값을 제공하지 않으며, SEMI E37의 값으로 대체하지도 않습니다. |
참고
- 예외
pdcomm::Error: 주소가 숫자 소켓 주소가 아니거나 옵션이 잘못되었으면PDCOMM_INVALID_ARGUMENT입니다. 잘못된 옵션의 예로 0인 타이머, 잘못된version또는struct_size, 0이 아닌reserved필드, 알 수 없는mode가 있습니다.max_events가 72보다 작거나,max_write_bytes가max_frame_bytes보다 작거나,max_application_bytes가max_frame_bytes에서 14를 뺀 값보다 작으면PDCOMM_LIMIT_EXCEEDED입니다. 수동 모드의 수신 대기 소켓을 바인딩할 수 없으면PDCOMM_IO_ERROR입니다. 그 밖에PDCOMM_ALLOCATION_FAILED또는PDCOMM_INTERNAL_ERROR일 수 있습니다.
TcpEndpoint
생성자
주소 문자열로 HSMS 끝점을 만듭니다.
TcpEndpoint(const std::string &address, const PdcommTcpOptions &options)address의 바이트로 포인터와 길이를 받는 생성자를 호출한 것과 같습니다.
매개변수
| 이름 | 설명 |
|---|---|
address | 127.0.0.1:5000이나 [::1]:5000 같은 숫자 소켓 주소입니다. 호스트 이름은 해석하지 않습니다. |
options | 끝점 구성입니다. 호출 중에 복사됩니다. |
참고
- 예외
pdcomm::Error: 포인터와 길이를 받는 생성자와 같은 상태 코드입니다.
cancel
메서드
pdcomm_tcp_cancel()로 열린 거래(transaction)를 취소합니다.
bool cancel(PdcommTcpToken token)취소된 거래는 PDCOMM_TCP_CANCELLED와 함께 PDCOMM_TCP_FAILED 이벤트를 발생시키며, 나중에 도착한 응답은 PDCOMM_TCP_UNEXPECTED_REPLY로 보고됩니다. 아직 쓰지 않은 큐의 프레임은 버려집니다. 일부만 쓴 프레임을 취소하면 연결이 닫힙니다. 이미 회선에 나간 바이트는 되돌릴 수 없기 때문입니다.
매개변수
| 이름 | 설명 |
|---|---|
token | request(), select(), deselect(), linktest()에서 받은 토큰입니다. reserved는 0이어야 합니다. |
반환값
열린 거래를 취소했으면 true, 이미 끝난 거래이면 false입니다.
참고
- 예외
pdcomm::Error:token.reserved가 0이 아니면PDCOMM_INVALID_ARGUMENT입니다. 토큰이 다른 끝점이나 이전 세대에 속하면PDCOMM_STALE_TOKEN입니다. 보류된 이벤트가 있거나, 이벤트 큐가 가득 찼거나, 끝점이 정지 중이면PDCOMM_BACKPRESSURE입니다.PDCOMM_POISONED일 수도 있습니다.
deselect
메서드
SELECTED 상태에서 벗어나기 위해 pdcomm_tcp_deselect()로 Deselect.req를 보냅니다.
PdcommTcpToken deselect()상대가 DeselectStatus 0으로 응답하면 열린 거래(transaction)는 모두 PDCOMM_TCP_DESELECTED로 실패하고, 응답하지 않은 수신 1차 메시지는 버려지며, 끝점은 T7 타이머가 동작하는 NOT SELECTED 상태로 돌아갑니다. 상태가 0이 아니면 반환된 토큰에 대해 PDCOMM_TCP_DESELECT_STATUS와 함께 PDCOMM_TCP_FAILED 이벤트가 발생합니다. HSMS-SS(SEMI E37.1)만 구현한 상대는 Deselect를 지원하지 않을 수 있습니다.
반환값
제어 거래 토큰입니다.
참고
- 예외
pdcomm::Error: 끝점이 SELECTED 상태가 아니면PDCOMM_INVALID_STATE입니다. Deselect가 이미 진행 중이거나, 거래 슬롯을 모두 사용 중이거나, 보류된 이벤트가 있거나, 큐가 가득 찼거나, 끝점이 정지 중이면PDCOMM_BACKPRESSURE입니다. 시스템 바이트가 소진되면PDCOMM_LIMIT_EXCEEDED입니다.PDCOMM_POISONED일 수도 있습니다.
isPending
메서드
pdcomm_tcp_is_pending()으로 거래가 아직 응답을 기다리는지 알려 줍니다.
bool isPending(PdcommTcpToken token) constW 비트 없이 보낸 요청의 토큰은 대기 중 상태가 되지 않습니다. 이 호출은 보류된 이벤트가 있어도 동작합니다.
매개변수
| 이름 | 설명 |
|---|---|
token | 확인할 토큰입니다. reserved는 0이어야 합니다. |
반환값
거래가 열려 있는 동안 true입니다.
참고
- 예외
pdcomm::Error:token.reserved가 0이 아니면PDCOMM_INVALID_ARGUMENT입니다. 토큰이 다른 끝점이나 이전 세대에 속하면PDCOMM_STALE_TOKEN입니다.PDCOMM_POISONED일 수도 있습니다.
linktest
메서드
연결이 살아 있는지 확인하기 위해 pdcomm_tcp_linktest()로 Linktest.req를 보냅니다.
PdcommTcpToken linktest()Linktest.rsp를 정상적으로 받으면 이벤트가 발생하지 않습니다. 토큰이 더 이상 대기 중 상태가 아니게 될 뿐입니다(isPending() 참고). 응답이 없으면 PDCOMM_TCP_T6_TIMEOUT과 함께 PDCOMM_TCP_FAILED 이벤트가 발생하고 연결이 닫힙니다. 한 번에 Linktest 하나만 진행할 수 있습니다.
반환값
제어 거래 토큰입니다.
참고
- 예외
pdcomm::Error: 끝점이 연결되어 있지 않으면(NOT SELECTED 또는 SELECTED 상태가 아니면)PDCOMM_INVALID_STATE입니다. Linktest가 이미 진행 중이거나, 거래 슬롯을 모두 사용 중이거나, 보류된 이벤트가 있거나, 큐가 가득 찼거나, 끝점이 정지 중이면PDCOMM_BACKPRESSURE입니다. 시스템 바이트가 소진되면PDCOMM_LIMIT_EXCEEDED입니다.PDCOMM_POISONED일 수도 있습니다.
localAddress
메서드
로컬 소켓 주소를 텍스트로 반환합니다.
std::string localAddress() const수동 끝점은 수신 대기 소켓을 소유하는 동안 수신 대기 주소를 알려 줍니다. 생성부터 stop()까지, 그리고 start() 이후에 다시 알려 줍니다. 포트 0에 대해 선택된 포트를 확인할 때 사용합니다. 능동 끝점은 현재 연결의 로컬 주소를 알려 줍니다.
반환값
127.0.0.1:5000이나 [::1]:5000 같은 주소입니다. 최대 80바이트입니다.
참고
- 예외
pdcomm::Error: 수신 대기 소켓이나 연결이 없거나 운영 체제가 주소를 알려 주지 못하면PDCOMM_IO_ERROR입니다.PDCOMM_POISONED일 수도 있습니다.
nativeHandle
메서드
C API를 직접 호출할 때 쓸, 소유 중인 네이티브 핸들을 반환합니다.
PdcommTcpEndpoint *nativeHandle() noexcept반환값
핸들입니다. 빈 끝점이면 nullptr입니다. 소유권은 이 래퍼에 남습니다.
nativeHandle
메서드
읽기 전용 C API 호출에 쓸, 소유 중인 네이티브 핸들을 반환합니다.
const PdcommTcpEndpoint *nativeHandle() const noexcept반환값
핸들입니다. 빈 끝점이면 nullptr입니다. 소유권은 이 래퍼에 남습니다.
nextEvent
메서드
pdcomm_tcp_next_event()로 끝점의 이벤트 큐에서 가장 오래된 이벤트를 꺼냅니다.
TcpEvent nextEvent()이벤트는 발생한 순서대로 반환됩니다. poll()을 호출할 때마다 큐를 비워야 합니다. 큐가 가득 차 있는 동안 끝점은 이후 이벤트를 내보내지 않고 보관합니다.
반환값
다음 이벤트입니다. 큐가 비어 있으면 빈 TcpEvent입니다.
참고
- 예외
pdcomm::Error: 이벤트를 할당하지 못하면PDCOMM_ALLOCATION_FAILED입니다. 이때 이벤트는 보류된 채로 남고 다음 호출이 그 이벤트를 반환합니다. 그때까지 start(), stop(), poll(), 제출 호출, cancel()은PDCOMM_BACKPRESSURE로 예외를 던집니다.PDCOMM_POISONED일 수도 있습니다. - GEM 역할이 연결되어 있어도 모든 이벤트는 여기서 가져와 GemEndpoint::handleEvent()에 전달합니다.
operator bool
메서드
래퍼가 네이티브 끝점을 소유하는지 알려 줍니다.
explicit operator bool() const noexcept반환값
끝점을 소유하면 true입니다.
operator=
메서드
현재 핸들을 해제한 뒤 other가 소유한 핸들의 소유권을 가져옵니다.
TcpEndpoint &operator=(TcpEndpoint &&other) noexcept해제하면 소멸자와 마찬가지로 현재 끝점의 소켓을 즉시 닫습니다.
매개변수
| 이름 | 설명 |
|---|---|
other | 원본 래퍼입니다. 호출 후 비게 됩니다. |
반환값
이 래퍼입니다.
operator=
메서드
복사 대입을 할 수 없습니다. 래퍼가 네이티브 핸들을 단독으로 소유합니다.
TcpEndpoint &operator=(const TcpEndpoint &) = deletepoll
메서드
pdcomm_tcp_poll()로 대기 중인 소켓 I/O와 HSMS 타이머 처리를 수행합니다.
size_t poll()한 번 호출에 최대 PdcommTcpOptions::poll_budget개의 내부 작업을 수행합니다. 내부 작업에는 연결 또는 수락, 프레임 읽기와 쓰기, 제어 메시지 응답, T3, T5, T6, T7, T8 타이머 만료 처리, 결과를 이벤트 큐로 옮기기가 있습니다. 결과는 nextEvent()로 가져옵니다. 연결 자체의 실패는 예외가 아니라 이벤트로 도착합니다.
반환값
진행된 내부 작업 수입니다. 큐에 들어간 이벤트 수가 아닙니다.
참고
- 예외
pdcomm::Error: 보류된 이벤트가 있거나 내부 큐가 결과를 더 받을 수 없으면PDCOMM_BACKPRESSURE입니다. 연결 수락에 실패하면PDCOMM_IO_ERROR입니다. 타이머 기한이 오버플로되면PDCOMM_LIMIT_EXCEEDED입니다. 단조 시계(monotonic clock)가 거꾸로 가면PDCOMM_INTERNAL_ERROR입니다.PDCOMM_POISONED일 수도 있습니다. - 능동 연결 시도는 이 호출을 최대
PdcommTcpOptions::connect_timeout_ms동안 블로킹합니다. 이벤트 큐가 비었다고 세션이 끝난 것은 아닙니다. 끝점을 사용하는 동안에는 계속 폴링합니다. - GEM 역할이 연결되어 있으면 이 호출은 GEM 상태도 갱신합니다.
reply
메서드
W 비트가 설정된 수신 1차 메시지에 대한 응답을 벡터에 담긴 본문으로 제출합니다.
void reply(const TcpEvent &primary, uint8_t stream, uint8_t function, bool wait, const std::vector<uint8_t> &body)body의 바이트로 포인터와 길이를 받는 오버로드를 호출한 것과 같습니다. 빈 벡터를 전달하면 본문 없는 응답을 보냅니다.
매개변수
| 이름 | 설명 |
|---|---|
primary | 1차 메시지의 PDCOMM_TCP_RECEIVED 이벤트입니다. 읽기만 합니다. |
stream | SECS-II 스트림입니다. 1차 메시지의 스트림과 같아야 합니다. |
function | 1차 메시지의 펑션에 1을 더한 값이거나, SxF0 중단(abort) 응답이면 0입니다. |
wait | 응답은 W 비트를 설정할 수 없으므로 false여야 합니다. |
body | 완전히 인코딩된 SECS-II 아이템 하나 또는 빈 벡터입니다. 호출 중에만 읽습니다. |
참고
- 예외
pdcomm::Error: 포인터와 길이를 받는 오버로드와 같은 상태 코드입니다.
reply
메서드
W 비트가 설정된 수신 1차 메시지에 대한 응답을 pdcomm_tcp_reply()로 제출합니다.
void reply(const TcpEvent &primary, uint8_t stream, uint8_t function, bool wait, const uint8_t *body, size_t bodyLength)응답은 1차 메시지의 시스템 바이트를 재사용합니다. W 비트가 설정된 1차 메시지는 응답하거나 연결이 Deselect되거나 닫힐 때까지 PDCOMM_TCP_MAX_TRANSACTIONS개의 수신 슬롯 중 하나를 차지합니다. 따라서 모든 메시지에 응답해야 합니다. 본문은 검증한 뒤 복사합니다. 성공은 응답이 큐에 들어갔다는 뜻일 뿐입니다.
매개변수
| 이름 | 설명 |
|---|---|
primary | 이 끝점의 현재 세대에서 받은 1차 메시지의 PDCOMM_TCP_RECEIVED 이벤트입니다. 읽기만 하며, 소유권은 호출자에게 남습니다. |
stream | SECS-II 스트림입니다. 1차 메시지의 스트림과 같아야 합니다. |
function | 1차 메시지의 펑션에 1을 더한 값이거나, SxF0 중단(abort) 응답이면 0입니다. |
wait | 응답은 W 비트를 설정할 수 없으므로 false여야 합니다. |
body | 완전히 인코딩된 SECS-II 아이템 하나입니다. 본문이 없는 응답이면 nullptr과 bodyLength 0을 전달합니다. 호출 중에만 읽습니다. |
bodyLength | body의 바이트 수입니다. 최대 max_frame_bytes에서 14를 뺀 값입니다. |
참고
- 예외
pdcomm::Error:primary가 비어 있거나 수신한 1차 메시지가 아니거나, 1차 메시지에 W 비트가 없거나 이미 응답했거나,stream,function,wait가 유효한 응답을 이루지 않거나,body가nullptr인데 길이가 0이 아니거나, 본문이 한 프레임에 들어가지 않으면PDCOMM_INVALID_ARGUMENT입니다.primary가 다른 끝점이나 이전 세대에서 왔으면PDCOMM_STALE_TOKEN입니다. 본문이 잘못되었거나 너무 크면PDCOMM_INVALID_DATA또는PDCOMM_LIMIT_EXCEEDED입니다. 끝점이 SELECTED 상태가 아니면PDCOMM_INVALID_STATE입니다. 보류된 이벤트가 있거나, 큐가 가득 찼거나, 끝점이 정지 중이면PDCOMM_BACKPRESSURE입니다.PDCOMM_POISONED일 수도 있습니다. - GEM 역할이 연결되어 있으면 라이브러리가 많은 1차 메시지에 직접 응답하고, 나머지는 respond 호출로 응답합니다. 이 호출은 GemEndpoint::handleEvent()가 GemResultKind::Unhandled로 보고한 1차 메시지에 사용합니다.
request
메서드
벡터에 담긴 본문으로 1차 데이터 메시지를 제출합니다.
PdcommTcpToken request(uint8_t stream, uint8_t function, bool wait, const std::vector<uint8_t> &body)body의 바이트로 포인터와 길이를 받는 오버로드를 호출한 것과 같습니다. 빈 벡터를 전달하면 본문 없는 메시지를 보냅니다.
매개변수
| 이름 | 설명 |
|---|---|
stream | SECS-II 스트림(0~127)입니다. |
function | SECS-II 펑션입니다. 홀수(1차 메시지)여야 합니다. wait를 설정하면 255이면 안 됩니다. |
wait | W 비트를 설정하고 응답을 기다리려면 true입니다. |
body | 완전히 인코딩된 SECS-II 아이템 하나 또는 빈 벡터입니다. 호출 중에만 읽습니다. |
반환값
거래 토큰입니다.
참고
- 예외
pdcomm::Error: 포인터와 길이를 받는 오버로드와 같은 상태 코드입니다.
request
메서드
pdcomm_tcp_request()로 1차 데이터 메시지를 제출합니다.
PdcommTcpToken request(uint8_t stream, uint8_t function, bool wait, const uint8_t *body, size_t bodyLength)본문은 PdcommTcpOptions::item_limits로 검증한 뒤 복사하므로, 호출이 반환되면 해제해도 됩니다. wait를 설정하면 W 비트를 설정하고 끝점이 거래(transaction)를 엽니다. 일치하는 응답은 is_reply가 설정되고 이 토큰을 가진 PDCOMM_TCP_RECEIVED 이벤트로 도착합니다. 그렇지 않으면 예를 들어 T3 응답 타임아웃 뒤에 PDCOMM_TCP_FAILED 이벤트로 거래가 끝납니다. wait를 설정하지 않으면 응답을 추적하지 않으며, 프레임을 로컬 소켓에 쓰면 PDCOMM_TCP_W0_WRITTEN 이벤트로 알려 줍니다.
매개변수
| 이름 | 설명 |
|---|---|
stream | SECS-II 스트림(0~127)입니다. |
function | SECS-II 펑션입니다. 홀수(1차 메시지)여야 합니다. wait를 설정하면 255이면 안 됩니다. |
wait | W 비트를 설정하고 응답을 기다리려면 true입니다. |
body | 완전히 인코딩된 SECS-II 아이템 하나입니다. 본문이 없는 메시지이면 nullptr과 bodyLength 0을 전달합니다. 호출 중에만 읽습니다. |
bodyLength | body의 바이트 수입니다. 최대 max_frame_bytes에서 14를 뺀 값입니다. |
반환값
거래 토큰입니다. 응답이나 실패 이벤트와 대조하거나 cancel() 또는 isPending()을 호출하려면 보관합니다.
참고
- 예외
pdcomm::Error: 끝점이 SELECTED 상태가 아니면PDCOMM_INVALID_STATE입니다.stream이나function이 잘못되었거나,body가nullptr인데 길이가 0이 아니거나, 본문이 한 프레임에 들어가지 않으면PDCOMM_INVALID_ARGUMENT입니다. 본문이 유효한 SECS-II 아이템 정확히 하나가 아니면PDCOMM_INVALID_DATA입니다. 본문이item_limits를 초과하거나 시스템 바이트가 소진되면PDCOMM_LIMIT_EXCEEDED입니다. 보류된 이벤트가 있거나, 거래 슬롯을 모두 사용 중이거나, 큐가 가득 찼거나, 끝점이 정지 중이면PDCOMM_BACKPRESSURE입니다.PDCOMM_POISONED일 수도 있습니다.
select
메서드
SELECTED 상태로 들어가기 위해 pdcomm_tcp_select()로 Select.req를 보냅니다.
PdcommTcpToken select()능동 끝점은 연결할 때마다 이미 Select.req를 자동으로 보냅니다. 이 호출은 Deselect 뒤나 Select가 거부된 뒤에 다시 Select할 때 사용합니다. 성공하면 끝점이 PDCOMM_TCP_SELECTED로 바뀌며, 이는 PDCOMM_TCP_STATE_CHANGED 이벤트로 보고됩니다. 실패하면 반환된 토큰에 대해 PDCOMM_TCP_FAILED 이벤트가 발생합니다. 예를 들어 PDCOMM_TCP_SELECT_STATUS나 PDCOMM_TCP_T6_TIMEOUT이 함께 옵니다.
반환값
제어 거래 토큰입니다.
참고
- 예외
pdcomm::Error: 끝점이 NOT SELECTED 상태가 아니면PDCOMM_INVALID_STATE입니다. Select가 이미 진행 중이거나, 거래 슬롯을 모두 사용 중이거나, 보류된 이벤트가 있거나, 큐가 가득 찼거나, 끝점이 정지 중이면PDCOMM_BACKPRESSURE입니다. 시스템 바이트가 소진되면PDCOMM_LIMIT_EXCEEDED입니다.PDCOMM_POISONED일 수도 있습니다.
start
메서드
pdcomm_tcp_start()로 새 연결 세대(generation)를 시작합니다.
void start()끝점은 세대를 1 늘리고 연결(능동) 또는 수신 대기(수동)를 시작합니다. 이 호출에서는 연결하지 않습니다. 연결이나 수락은 poll()이 수행합니다. 정지한 뒤에는 수동 끝점이 수신 대기 소켓을 다시 바인딩합니다.
참고
- 예외
pdcomm::Error: 끝점이 정지 상태가 아니거나 이전 연결을 아직 닫는 중이면PDCOMM_INVALID_STATE입니다. 보류된 이벤트가 있거나 이벤트 큐가 가득 차면PDCOMM_BACKPRESSURE입니다. 수동 소켓을 다시 바인딩할 수 없으면PDCOMM_IO_ERROR입니다.PDCOMM_POISONED일 수도 있습니다. - GEM 역할이 연결되어 있으면 이 호출은 GEM 상태도 갱신합니다.
state
메서드
끝점 식별자, 세대, HSMS 상태, 종료 상태를 읽습니다.
PdcommTcpState state() conststate에는 PDCOMM_TCP_SELECTED 같은 PDCOMM_TCP_* 상태 값이 들어 있습니다. closed는 stop() 이후 연결이 닫히고 내부 작업이 끝났을 때만 1이 됩니다. 모든 이벤트를 가져왔다는 뜻은 아닙니다. 이 호출은 보류된 이벤트가 있어도 동작합니다.
반환값
pdcomm_tcp_state()가 채운 스냅숏입니다.
참고
- 예외
pdcomm::Error:PDCOMM_POISONED입니다.
stop
메서드
pdcomm_tcp_stop()으로 끝점을 정지하고 정상 종료를 시작합니다.
void stop()SELECTED 상태이면 끝점은 Separate.req를 큐에 넣습니다. 열린 거래(transaction)는 모두 PDCOMM_TCP_CANCELLED로 실패하고, 응답하지 않은 수신 1차 메시지는 버려지며, 상태는 PDCOMM_TCP_STOPPED가 됩니다. poll()이 큐의 프레임을 쓰는 동안 연결은 최대 PdcommTcpOptions::shutdown_timeout_ms 동안 열려 있습니다. 따라서 state().closed가 1이 될 때까지 계속 폴링하며 이벤트를 꺼냅니다. 정지 중에 다시 정지해도 효과가 없으며, 한 번도 시작하지 않은 끝점을 정지해도 성공합니다.
참고
- 예외
pdcomm::Error: 보류된 이벤트가 있거나 이벤트 큐에 종료 이벤트를 담을 수 없으면PDCOMM_BACKPRESSURE입니다.PDCOMM_POISONED일 수도 있습니다. - GEM 역할이 연결되어 있으면 이 호출은 GEM 상태도 갱신합니다.
~TcpEndpoint
메서드
pdcomm_tcp_destroy()로 끝점과 소켓을 해제합니다.
~TcpEndpoint()소켓은 즉시 닫히며, 회선상의 정상적인 HSMS 종료 절차는 보장하지 않습니다. 정상 종료하려면 먼저 stop()을 호출하고, state().closed가 1이 될 때까지 계속 폴링하며 이벤트를 꺼냅니다. 이전에 얻은 이벤트와 GEM 결과는 계속 유효합니다. 빈 끝점은 아무것도 해제하지 않습니다.