问题有三:一、关于输入流:
1、通过带缓冲区的InputStream扩展类,可以一次获得服务器发出的需要协商的所有命令消息,这正常吗?
2、我是否必须一条条展开协商(譬如先协商第一条),还是可以根据需要对认为需要协商的发送相应的字节到输出流上,可不可以按照需要打乱协议的顺序(譬如先协商终端协议再协商echo协议)?
3、可否在输出流上一次将多条协商命令同时发出?(这条涉及输出流了)具体如下:
通过 Socket mySocket = new Socket("127.0.0.1",23); 建立连接后
din = new DataInputStream(mySocket.getInputStream());
byte[] ch = new byte[1024];
int leng = din.read(ch);
ch[]中存放:-1, -3, 37, -1, -5, 1, -1, -5, 3, -1, -3, 39, -1, -3, 31, -1, -3, 0, -1, -5, 0
即收到了所有telnet 协议(RFC 845)中的服务器方消息(将int型的数值转换成byte的形式)
如果我同意其他协议,仅对终端类型协议展开协商
可否对输出流直接操作还是??二、关于输出流
1、telnet 协议(RFC 845)中规定IAC=255,但是字节型的oxFF值为-1
同时telnet协议传输的就是字节,那我是否可以直接在输出流上用字节变量-1代表IAC?还是必须作必要转换
2、IAC IAC是什么意思,协议解释的不太清楚
3、同输入流问题(3)三、关于循环调用
1、协商中如果必须一条条协商,那么如何应用缓冲区实现?
2、协商结束,建立TELNET连接后,每次读取并显示完输入流中的数据后,应该等待键盘输入命令。
请问如何判断已经读完单次数据流?
如何在每次键盘命令输入完成时,将命令输入输出流?
如何循环实现以上几步(因为键盘输入是不可预期的)
3、如何在不可预期的键盘输入下,循环执行输入输出流
即:
输入流完全读完——>等待键盘输入——>执行键盘输入完毕——>执行输出流
      |                                                     |   
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                       (再次执行输入流,循环执行) 
以上问题困扰小弟很久,因为水平有限看过经典代码仍无所获,
以往高手就每个问题详细讲解
初学者,望各位高手指教

解决方案 »

  1.   

    我刚刚做了http的解析,对于telnet还不了解。不过我做的输入流一般是每次读取一行,也就是in.readline();因为每行都有\r\n结尾,不知道telnet是不是这样?我估计一次获得服务器发出的需要协商的所有命令消息是有可能的(没试过,猜测),但是只能用read(),还要自己控制结尾的标识符和读取数据的长度。
      

  2.   

    推荐lz去看下apache的开源mina项目
    mina.pache.org里面有telnet的一个例子
    另外,现在都用nio来开发了,普通的socket早过时了
      

  3.   

    修正下mina的地址:http://mina.apache.org/
      

  4.   

    多谢楼上
    看过NIO的说明,还是非常有帮助TO: zhwh(韩信) 
    因为telnet协议采用字节输入
    所以不支持in.readLine()
    还有就是,理论上应该有命令结束符CR或者CR/LF
    但是测试中发现什么结束符都没有受到
    而且会始终等待接受下一个字符
    如果采用断点调试却可以通过具体代码可以参考另一个贴
    http://community.csdn.net/Expert/topic/5498/5498919.xml?temp=.5091516
      

  5.   

    第一次接收到的数据是telnet另一方发送的协商指令
    每个协商指令为3个字节 如:IAC WILL BINARY 数字代表(十进制):255 251 0 
    由于指令传输是用二进制传输的,所以读取时应该用byte数组来装。byte中的255是与-1是等价的(因为NVT比对是按位比对的)。第一次接收的数据有21个字节,也就是说有7个协商请求。如果对选项没有特殊要求,可以对7个协商请求中的每个will请求进行dont回复,对每个do请求进行wont回复。
    如:IAC WILL BINARY ,数字代表(十进制):255 251 0  则回复为:IAC DONT BINARY 数字代表为:255 254 0  即只需要修改will的值 而且假设该请求是放在byte数组ch[]的第一个位置,你所做的操作:ch[1]=254. 当7个请求的回复都已经设置完成,将此ch[]写到输出流中,即发送给telnet另一方。注:如果对选项有特殊要求,请仔细阅读telnet协议。那个将会相当复杂,会出现子选项的协商,请求格式也将不会只是3个字节。IAC 如果一段数据以IAC开头就是标识这一段是协商请求。你需要提取ch[]中的IAC来确定请求的个数,每个请求的长度。
    是否读完数据流中的数据不需要判断,全部读取就ok读取键盘的数据这个用java的事件机制完成。至于读取的命令或者数据是否是应该读取的,这里不再详细说明(可以设置读取位置与结束位置) 读取键盘信息用死循环读取