public class MyWhoisClient {
public static void main(String [] args){
String host="whois.internic.net";
int port=43;
try{
InetAddress hostAddress=InetAddress.getByName(host);
Socket socket=new Socket(hostAddress,port);
OutputStream out=socket.getOutputStream();
out=new BufferedOutputStream(out);
Writer writer=new OutputStreamWriter(out,"8859_1");
for(int i=0;i<args.length;i++)
writer.write(args[i]+" ");
writer.write("\r\n");
writer.flush();
//socket.shutdownOutput(); //去掉此行注释,无法获得响应
InputStream in=socket.getInputStream();//IO是否阻塞
in=new BufferedInputStream(in);
int c=0;
while((c=in.read())!=-1)
System.out.write(c);//c为整型,为什么输出为字符
}catch(Exception e){
e.printStackTrace();
}
}
}
程序功能:键入关键词,向whois服务器查询结果。例如:
java MyWhoisClient abs
获得结果如下:
ABS.COM.MX
ABS.COM.MORE.INFO.AT.WWW.BEYONDWHOIS.COM
ABS.ABS.COM.MY
ABS.NET
ABS.EDU
ABS.COM问题:
1.flush后马上关闭socket的输出流,程序无法从服务器获得响应。flush后缓冲区的数据应该发送出去了,关闭输出流应该没关系,但从程序看似乎不是这样。为什么?
2.将writer.flush()改为out.flush为什么也不行。out是个OutputStream,封装在Writer中。writer.flush可以清空缓冲区,
out.flush不行,为什么?
3.把writer.flush()也注释掉,为什么也无法获得响应?
4.数据发送出去后IO是否阻塞,等待接收到响应再继续往下执行?
5.c为整型,为什么输出为字符?
问题比较多,麻烦各位大大帮忙看看,呵呵。

解决方案 »

  1.   

    5. read()每次就返回一个字节,这个字节就是一个字符。write的时候,也是一个字节。如果你换成print就会将数值字符串打印出来。
    4. 发送完成后,服务器收到\r\n才确认输入完成,才有响应回来。有阻塞也不是在客户端,而在于服务端没完成发送。
    3. 底层用了buffered...,所以应该flush,防止不及时送出
    2. 这是不是Writer和OutputStream之间的关系决定的,同问。
    1. 其实我觉得shutdownOutput只是发一个关闭信号,又不是close,应该没问题。这是不是whois协议决定的。同问。
      

  2.   

    谢谢magong的回复。
    5.查过文档,read返回的是0~255的整型。是不是write函数自动把数值编码为字符?如果把write改成print的话什么都不会输出,奇怪。
    4.不阻塞的话发送数据后继续往下执行。程序执行的速度肯定比网络传输要快,当运行到while时响应还没传回来,怎么会有输出呢?
    3应该就是你讲的那样,呵呵,很高兴和你讨论。
      

  3.   

    如果把write改成print的话运行时没输出,debug才有,奇怪。
      

  4.   

    5. print应该有输出啊,我的就有。
    JDK中对OutputStream.write方法的描述是:将指定的字节写入此输出流。 write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。 b 的24 个高位将被忽略。
    4. 到while的时候,read会阻塞。共同学习吧。谢谢。
      

  5.   

    我的还是没输出,怪了。
    第3点,刚试了下,不用buffer,把flush语句注释掉服务器也没有响应此时是不是没有数据发送到服务器?或者在数据发回来之前程序就结束了。这样的话就read就不存在阻塞的情况了。
    不输入参数的话也是一样,程序马上结束,没有等待read
      

  6.   

    恩。进一步不用writer,直接用outputStream就可以不用flush了。