700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > telnet深度解析 – CSS – 前端 css图片手风琴效果代码

telnet深度解析 – CSS – 前端 css图片手风琴效果代码

时间:2019-05-08 22:32:40

相关推荐

telnet深度解析 – CSS – 前端 css图片手风琴效果代码

下面的debug信息来自与/tmp/telenet.debug文件的一部分。

是客户端按下字母e后发生的四个阶段。这篇主要分析第一阶段和第二阶段。

也就是telrcv函数的主要的功能。

td: netread 1 chars

nd: 65 e

td: ptyflush 1 chars

pd: 65 e

td: ptyread 2 chars

pd: 0065 .e

td: netflush 1 chars

下面的是telnetd.c里面最主要的一个函数,其中里面的for循环也是理解telnetd的工作机制最主要的部分。

int

telnetd_run (void)

{

for (;;)

{

fd_set ibits, obits, xbits;

register int c;

if (net_input_level () < 0 && pty_input_level () < 0)

break;

FD_ZERO (&ibits);

FD_ZERO (&obits);

FD_ZERO (&xbits);

/* Never look for input if there’s still stuff in the corresponding

output buffer */

if (net_output_level () || pty_input_level () > 0)

FD_SET (net, &obits);

else

FD_SET (pty, &ibits);

if (pty_output_level () || net_input_level () > 0)

FD_SET (pty, &obits);

else

FD_SET (net, &ibits);

if (!SYNCHing)

FD_SET (net, &xbits);

if ((c = select (nfd, &ibits, &obits, &xbits, NULL)) <= 0)

{

if (c == -1 && errno == EINTR)

continue;

sleep (5);

continue;

}

if (FD_ISSET (net, &xbits))

SYNCHing = 1;

if (FD_ISSET (net, &ibits))

{

/* Something to read from the network… */

/*FIXME: handle !defined(SO_OOBINLINE) */

net_read ();这里是第一阶段执行的函数

}

if (FD_ISSET (pty, &ibits))

{

/* Something to read from the pty… */

if (pty_read () <= 0)

break;

/* The first byte is now TIOCPKT data. Peek at it. */

c = pty_get_char (1);

#if defined TIOCPKT_IOCTL

if (c & TIOCPKT_IOCTL)

{

pty_get_char (0);

copy_termbuf (); /* Pty buffer is now emptied. */

localstat ();

}

#endif

if (c & TIOCPKT_FLUSHWRITE)

{

static char flushdata[] = { IAC, DM };

pty_get_char (0);

netclear (); /* clear buffer back */

net_output_datalen (flushdata, sizeof (flushdata));

set_neturg ();

DEBUG (debug_options, 1, printoption (“td: send IAC”, DM));

}

if (his_state_is_will (TELOPT_LFLOW)

&& (c & (TIOCPKT_NOSTOP | TIOCPKT_DOSTOP)))

{

int newflow = (c & TIOCPKT_DOSTOP) ? 1 : 0;

if (newflow != flowmode)

{

net_output_data (“%c%c%c%c%c%c”,

IAC, SB, TELOPT_LFLOW,

flowmode ? LFLOW_ON : LFLOW_OFF, IAC, SE);

}

}

pty_get_char (0); /* Discard the TIOCPKT preamble. */

}

while (pty_input_level () > 0)

{

if (net_buffer_is_full ())

break;

c = pty_get_char (0);

if (c == IAC)

net_output_byte (c);

net_output_byte (c);

if (c == ‘\r’ && my_state_is_wont (TELOPT_BINARY))

{

if (pty_input_level () > 0 && pty_get_char (1) == ‘\n’)

net_output_byte (pty_get_char (0));

else

net_output_byte (0);

}

}

if (FD_ISSET (net, &obits) && net_output_level () > 0)

netflush ();

if (net_input_level () > 0)

telrcv ();

if (FD_ISSET (pty, &obits) && pty_output_level () > 0)

ptyflush (); 这里是第二阶段执行的函数。

/* Attending to the child must come last in the loop,

* so as to let pending data be flushed, mainly to the

* benefit of the remote and expecting client.

*/

if (pending_sigchld) {

/* Check for pending output, independently of OBITS. */

if (net_output_level () > 0)

netflush ();

cleanup (SIGCHLD); /* Not returning from this. */

}

}

net_read函数分析。这个函数是接收来自net的一个字符。

ncc是个数,用到的netibuf,网络输入缓冲区。可以这么理解。

netip是网络输入缓冲区的指针。

int

net_read (void)

{

ncc = read (net, netibuf, sizeof (netibuf));

if (ncc < 0 && errno == EWOULDBLOCK)

ncc = 0;

else if (ncc == 0)

{

syslog (LOG_INFO, “telnetd: peer died”);

cleanup (0);

/* NOT REACHED */

}

else if (ncc > 0)

{

netip = netibuf;

DEBUG (debug_report, 1,

debug_output_data (“td: netread %d chars\r\n”, ncc));

DEBUG (debug_net_data, 1, printdata (“nd”, netip, ncc));

}

return ncc;

}

telrcv函数是一个关键的函数,在文件state.c中定义。

和telnet协议状态机有关。

比如如果第一个字节是FF也就是IAC,那么下面的字节是命令字节。命令选项字节。

net_get_char函数和pty_output_byte函数是理解telrcv函数的主要的地方。

其他的语句都和状态机有关。这两个函数是取一个字符,函数放到pty缓冲区里。

void

telrcv (void)

{

register int c;

static int state = TS_DATA;

while ((net_input_level () > 0) & !pty_buffer_is_full ())

{

c = net_get_char (0);

#ifdef ENCRYPTION

if (decrypt_input)

c = (*decrypt_input) (c);

#endif /* ENCRYPTION */

switch (state)

{

case TS_CR:

state = TS_DATA;

/* Strip off \n or \0 after a \r */

if ((c == 0) || (c == ‘\n’))

break;

/* FALL THROUGH */

case TS_DATA:

if (c == IAC)

{

state = TS_IAC;

break;

}

/*

* We now map \r\n ==> \r for pragmatic reasons.

* Many client implementations send \r\n when

* the user hits the CarriageReturn key.

*

* We USED to map \r\n ==> \n, since \r\n says

* that we want to be in column 1 of the next

* printable line, and \n is the standard

* unix way of saying that (\r is only good

* if CRMOD is set, which it normally is).

*/

if ((c == ‘\r’) && his_state_is_wont (TELOPT_BINARY))

{

int nc = net_get_char (1);

#ifdef ENCRYPTION

if (decrypt_input)

nc = (*decrypt_input) (nc & 0xff);

#endif /* ENCRYPTION */

/*

* If we are operating in linemode,

* convert to local end-of-line.

*/

if (linemode

&& net_input_level () > 0

&& ((‘\n’ == nc) || (!nc && tty_iscrnl ())))

{

net_get_char (0); /* Remove from the buffer */

c = ‘\n’;

}

else

{

#ifdef ENCRYPTION

if (decrypt_input)

(*decrypt_input) (-1);

#endif /* ENCRYPTION */

state = TS_CR;

}

}

pty_output_byte (c);

break;

case TS_IAC:

gotiac:

switch (c)

{

/*

* Send the process on the pty side an

* interrupt. Do this with a NULL or

* interrupt char; depending on the tty mode.

*/

case IP:

DEBUG (debug_options, 1, printoption (“td: recv IAC”, c));

send_intr ();

break;

case BREAK:

DEBUG (debug_options, 1, printoption (“td: recv IAC”, c));

send_brk ();

break;

int

net_get_char (int peek)

{

if (peek)

return *netip;

else if (ncc > 0)

{

ncc–;

return *netip++ & 0377;

}

return 0;

}

void

pty_output_byte (int c)

{

*pfrontp++ = c;

}

这里是第二阶段相关的函数。比较好理解。

主要的功能是把缓冲区的字符放到/dev/pty里面

a b c d e f g

pbackppfrontp

上面的pfrontp指针指向的是字母g,如果再输入一个字符h,那么pfrontp指针就指向字符h。

上面的pbackp指针指向的是字母b,如果要拿出一个字符,那么应该先拿出字符b,然后是c,再然后是d。

void

ptyflush (void)

{

int n;

if ((n = pfrontp – pbackp) > 0)

{

DEBUG (debug_report, 1,

debug_output_data (“td: ptyflush %d chars\r\n”, n));

DEBUG (debug_pty_data, 1, printdata (“pd”, pbackp, n));

syslog (LOG_NOTICE, “ptyflush pbackp = %s”, pbackp);

n = write (pty, pbackp, n);

}

if (n < 0)

{

if (errno == EWOULDBLOCK || errno == EINTR)

return;

cleanup (0);

/* NOT REACHED */

}

pbackp += n;

if (pbackp == pfrontp)

pbackp = pfrontp = ptyobuf;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。