ΠΠ·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΡΠΌΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌΠΈ
Π Π°ΡΡΠΌΠΎΡΡΠ΅Π½Π½ΡΠΉ ΡΠ°Π½Π΅Π΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ TLI ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ TPI. ΠΠ΅Π³ΠΊΠΎ Π·Π°ΠΌΠ΅ΡΠΈΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ TLI ΠΈ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Π°ΠΌΠΈ TPI, ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΌΠΈ Π² ΡΠ°Π±Π».Β 6.10. Π‘Ρ Π΅ΠΌΠ° Π²ΡΠ·ΠΎΠ²Π° ΡΡΠ½ΠΊΡΠΈΠΉ TPI ΠΈ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌΠΈ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Π°ΠΌΠΈ TPI ΠΌΠ΅ΠΆΠ΄Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ Π΄Π»Ρ ΡΠΈΠΏΠΈΡΠ½ΠΎΠ³ΠΎ TCP-ΡΠ΅Π°Π½ΡΠ° ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° Π½Π° ΡΠΈΡ. 6.32.

Π ΠΈΡ. 6.32. Π€ΡΠ½ΠΊΡΠΈΠΈ TLI ΠΈ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Ρ TPI
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π±ΡΠ» ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½ Π² Π³Π»Π°Π²Π΅ 5 ΠΏΡΠΈ ΠΎΠ±ΡΡΠΆΠ΄Π΅Π½ΠΈΠΈ ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΡ STREAMS. ΠΡΠ½ΠΎΠ²Π½ΡΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ, ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡΠΈΠΌΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, ΡΠ²Π»ΡΡΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ Π²ΡΠ·ΠΎΠ²Ρ putmsg(2) ΠΈ getmsg(2). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΡΡΠ½ΠΊΡΠΈΠΉ TLI, ΡΠΎΡΡΠ°Π²Π»ΡΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΄ΠΎΡΡΡΠΏΠ° ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΠΊ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΠΌ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°ΠΌ, ΡΠ²Π»ΡΡΡΡΡ ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ ΠΎΠ±ΠΎΠ»ΠΎΡΠΊΠΎΠΉ (ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π² Π²ΠΈΠ΄Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, libnsl.so) Π±ΠΎΠ»Π΅Π΅ ΡΡΠ½Π΄Π°ΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΡΠΌ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠΌ Π²ΡΠ·ΠΎΠ²Π°ΠΌ putmsg(2) ΠΈ getmsg(2).
Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ ΡΡΠ½ΠΊΡΠΈΡ t_connect(3N). ΠΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΌΠΎΠΆΠ΅Ρ ΠΈΠΌΠ΅ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π²ΠΈΠ΄:
int t_connect(int fd, struct t_call *sndcall,struct t_call *recvcall) {Β struct T_conn_req *connreq;Β struct T_conn_con* conncon;Β struct T_ok_ack *okack;Β struct T_error_ack *errack;Β struct strbuf connect, ack, confirm, m_data;Β struct netbuf addr, opt, udata;Β char *buf;Β int flags;Β ...Β /* Π‘ΠΎΡ
ΡΠ°Π½ΠΈΠΌ Π°Π΄ΡΠ΅ΡΠ° Π±ΡΡΠ΅ΡΠΎΠ² netbuf Π·Π°ΠΏΡΠΎΡΠ° sndcall */Β addr = sndcall->addr; opt = sndcall->opt;Β udata = sndcall->udata;Β /* ΠΠ°ΠΏΠΎΠ»Π½ΠΈΠΌ ΠΏΠΎΠ»Ρ ΡΡΡΡΠΊΡΡΡΡ strbuf Π΄Π»Ρ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡΒ Β Β ΡΠΏΡΠ°Π²Π»ΡΡΡΠ΅ΠΉ ΡΠ°ΡΡΠΈ (Π±Π»ΠΎΠΊ M_PROTO) ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ T_CONN_REQ */Β connect.len =Β sizeof(struct T_conn_req) + addr.len + opt.len;Β connect.maxlen =Β sizeof(struct Π’_conn_req) + addr.maxlen + opt.maxlen;Β buf = (char*)malloc(connect.maxlen);Β connect.buf = buf;Β /* ΠΠ°ΠΏΠΎΠ»Π½ΠΈΠΌ ΠΏΠΎΠ»Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Π±Π»ΠΎΠΊΠ° M_PROTO ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ T_CONN_REQ Π²Β Β Β ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΈ Ρ ΡΠΎΡΠΌΠ°ΡΠΎΠΌ ΡΡΡΡΠΊΡΡΡΡ T_conn_req */Β connreq = (struct T_conn_req*)buf;Β connreq->PRIM_type = T_CONN_REQ;Β connreq->DEST_length = addr.len;Β connreq->DEST_offset = sizeof (struct T_conn_req);Β buf += sizeof(struct T_conn_req);Β memcpy(buf, addr.buf, addr.len);Β connreq->OPT_length = opt.len;Β connreq->OPT_offset = connreq->DEST_offset + opt.len;Β buf += addr.len;Β memcpy(buf, opt.buf, opt.len);Β /* ΠΠ°ΠΏΠΎΠ»Π½ΠΈΠΌ ΠΏΠΎΠ»Ρ ΡΡΡΡΠΊΡΡΡΡ strbuf Π΄Π»Ρ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½ΡΡ
Β Β Β (Π±Π»ΠΎΠΊ M_DATA) */Β m_data.len = udata.len;Β m_data.maxlen = udata.maxlen;Β m_data.buf = udata.buf;Β /* ΠΡΠΏΡΠ°Π²ΠΈΠΌ Π·Π°ΠΏΡΠΎΡ Π’_CONN_REQ ΠΏΠΎΡΡΠ°Π²ΡΠΈΠΊΡ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΡ
ΡΡΠ»ΡΠ³Β Β Β ΠΏΠΎ ΠΏΠΎΡΠΎΠΊΡ fd */Β putmsg(fd, &connect, &m_data, 0);Β /* ΠΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΠΌΡΡ ΠΊ ΠΏΡΠΈΠ΅ΠΌΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ. ΠΡΠ΄Π΅Π»ΠΈΠΌ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉΒ Β Β ΡΠ°Π·ΠΌΠ΅Ρ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π½Π΅Π³Π°ΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡΒ Β Β ΠΏΡΠΈΠΌΠΈΡΠΈΠ² T_ERROR_ACK Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ Π±ΠΎΠ»ΡΡΠ΅ ΠΌΠ΅ΡΡΠ° */Β ack.len = ack.maxlen = sizeof(struct T_error_ack);Β ack.buf = udata.buf;Β /* ΠΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠ½ΡΠΌ, ΠΏΠΎΡΡΠΎΠΌΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ ΡΠ»Π°Π³Β Β Β RS_HIPRI. ΠΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ Π½Π΅ ΠΏΡΠ΅Π΄ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌΒ Β Β Π½ΠΈΠΊΠ°ΠΊΠΈΡ
Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ */Β flags = RS_HIPRI;Β getmsg(fd, &ack, (struct strbuf*)0, &flags);Β free(connect.buf);Β okack = (struct T_ok_ack*)ack.buf;Β /* ΠΡΠΎΠ²Π΅ΡΠΈΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎ Π»ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΠΈΠ»ΠΈΒ Β Β Π½Π΅Π³Π°ΡΠΈΠ²Π½ΠΎΠ΅ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ */Β if (okack->PRIM_type == T_OK_ACK) {Β Β /* ΠΡΠ»ΠΈ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅, ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΠΌΡΡ ΠΊ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡΒ Β Β Β ΡΠΎΠ³Π»Π°ΡΠΈΡ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π° ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠ²ΡΠ·ΠΈΒ Β Β Β (ΠΏΡΠΈΠΌΠΈΡΠΈΠ² T_CONN_CON) */Β free(ack.buf);Β if (recvcall != NULL) {Β Β addr = recvcall->addr;Β Β opt = recvcall->opt;Β Β udata = recvcall->udata;Β Β confirm.len = sizeof(struct T_conn_con) + addr.len + opt.len;Β Β confirm.maxlen =Β Β Β sizeof(struct T_conn_con) + addr.maxlen + opt.maxlen;Β Β buf = (char*)malloc(confirm.maxlen);Β Β confirm.buf = buf;Β Β m_data.len = udata.len;Β Β m_data.maxlen = udata.maxlen;Β Β m_data.buf = udata.buf;Β Β /* ΠΠΎΠ»ΡΡΠΈΠΌ ΠΏΡΠΈΠΌΠΈΡΠΈΠ² T_CONN_CON */Β Β getmsg(fd, &confirm, &m_data, &flags);Β Β free(buf);Β Β conncon = (struct T_conn_con*)confirm.buf;