p> 整个程序结构比较简单,不想罗嗦了,这里只讲它的精华:waitstring的协商部分,使用这段代码,就能完成最头痛的协商,然后就可以随心所欲的编写自己的telnet应用了。阅读时请参考精华区-$#@62;Socket编程之绝学篇-$#@62;telnet编程中的telnet基本过程.
这里再罗嗦一下一些基本常识:
1.IAC(255)telnet的控制命令混杂在字节流里面,以这个255表明这是个三元协商队列,后跟verb和option
2.verb有四种类型Do(253)Dont(254)Will(251)Wnot(252).Do/Dont-$#@62;$#@60;-Will/Wnot
一方用Do向对方发出请求(Request),另一方用Will作答.如:Client发送IACDONTECHO要求Server不要回显字符,Server用IAC
WNOTECHO作答.Will/Wnot-$#@62;$#@60;-Do/Dont一方用Will指定自己(Offer),另一方用Do作答
3.option有四种0二进制传输1Echo3抑制向前24终端类型
4.子协商队列以255250开头255240结束
voidwaitString(char*string)/*从server发来的字节流中匹配特定串,找到就返回*/
{
charterm[]="dumb";/*终端类型:哑终端*/
unsignedcharc,cmd,opt;
for(;
{n=read(sockfd,&c,1);/*读取一个字节*/
if(n$#@60;=0)
{printf("socketreaderror.\n");exit(-1);}
if(c==255)
/*如果是IAC(255)字符,表明是server发过来的协商队列,将开始与server协?nbsp;
*/?nbsp;
{
cmd=receiveChar();//读入命令DO/DONT/WILL/WONT
opt=receiveChar();//读入选项0/1/3/24
switch(opt){
case1://echo协商选项,本程序未处理
break;
case3://supressgo-ahead(抑制向前选项)
break;
case24://terminaltype(终端类型选项)
if(cmd==253){
/*服务器发来DO(253),要求client回答Client用IACWILLTERMTYPE答应告诉server自己终端类型*/
sendChar((char)255);
sendChar((char)251);
sendChar((char)24);
/*开始用子协商序列回答自己的终端类型
*IACSBterminal-typeIS*/
sendChar((char)255);
sendChar((char)250);
sendChar((char)24);
sendChar((char)0);
sendString(term);
sendChar((char)255);
sendChar((char)240);
/*SB和SE要配对出现协商序列完毕*/
}
elseif(cmd==250){//server发来自己的终端类型
while(receiveChar()!=240)
;/*不作处理,直到server发完为止
SubnegotiationEnd( )*/
}
break;
default://someothercommand1
if(cmd==253){
//IACDONTwhatever
sendChar((char)255);//其它的协商选项均不同意
sendChar((char)252);
sendChar((char)opt);
}
}
}
}
}