Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма UNIXΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 148

Автор РобачСвский АндрСй ΠœΠΈΡ…Π°ΠΉΠ»ΠΎΠ²ΠΈΡ‡

ВзаимодСйствиС с ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹ΠΌΠΈ процСссами

РассмотрСнный Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ интСрфСйс TLI ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ TPI. Π›Π΅Π³ΠΊΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ соотвСтствиС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями TLI ΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°ΠΌΠΈ TPI, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌΠΈ Π² Ρ‚Π°Π±Π».Β 6.10. Π‘Ρ…Π΅ΠΌΠ° Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ TPI ΠΈ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°ΠΌΠΈ TPI ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром для Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠ³ΠΎ TCP-сСанса ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π½Π° рис. 6.32.

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма UNIX - img_121.jpeg

Рис. 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;