黑马程序员技术交流社区

标题: Socket编程的问题 [打印本页]

作者: masterV    时间: 2013-8-15 16:44
标题: Socket编程的问题
本帖最后由 魏先勇 于 2013-8-15 19:31 编辑

如下代码,我对照了一下毕老师的代码,只是毕老师用的是字节流,我这里转换成了字符流,其他没什么不同,但是当我运行的时候服务端和客户端都得不到结果,求解。
  1. import java.io.*;
  2. import java.net.*;

  3. class TcpClient2
  4. {
  5.         public static void main(String[] args) throws Exception
  6.         {
  7.                 InetAddress addr = InetAddress.getByName(null);
  8.                 Socket s = new Socket(addr, 10001);
  9.                 //这里把BufferedWriter换成PrintWriter程序就能执行,求解是我代码错误还是不能使用BufferedWriter。
  10.                 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
  11.                                 s.getOutputStream()));

  12.                 bufw.write("hello,server!");
  13.                 bufw.flush();

  14.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(
  15.                                 s.getInputStream()));
  16.                 String str = bufr.readLine();
  17.                 System.out.println(str);

  18.                 s.close();
  19.         }
  20. }

  21. class TcpServer2
  22. {
  23.         public static void main(String[] args) throws Exception
  24.         {
  25.         
  26.                 ServerSocket ss = new ServerSocket(10001);
  27.                 Socket s = ss.accept();

  28.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(
  29.                                 s.getInputStream()));

  30.                 String str = bufr.readLine();
  31.                 System.out.println(str);

  32.                 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
  33.                                 s.getOutputStream()));

  34.                 bufw.write(str.toUpperCase());
  35.                 bufw.flush();

  36.                 s.close();
  37.                 ss.close();
  38.                
  39.         }
  40. }
复制代码
附上可以执行的代码:
  1. import java.io.*;
  2. import java.net.*;

  3. class TcpClient2
  4. {
  5.         public static void main(String[] args) throws Exception
  6.         {
  7.                 InetAddress addr = InetAddress.getByName(null);
  8.                 Socket s = new Socket(addr, 10001);

  9.                 PrintWriter out = new PrintWriter(s.getOutputStream(), true);
  10.                 out.println("hello,server!");

  11.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(
  12.                                 s.getInputStream()));
  13.                 String str = bufr.readLine();
  14.                 System.out.println(str);

  15.                 s.close();
  16.         }
  17. }

  18. class TcpServer2
  19. {
  20.         public static void main(String[] args) throws Exception
  21.         {

  22.                 ServerSocket ss = new ServerSocket(10001);
  23.                 Socket s = ss.accept();

  24.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(
  25.                                 s.getInputStream()));

  26.                 String str = bufr.readLine();
  27.                 System.out.println(str);

  28.                 PrintWriter out = new PrintWriter(s.getOutputStream(), true);
  29.                 out.println(str.toUpperCase());

  30.                 s.close();
  31.                 ss.close();

  32.         }
  33. }
复制代码

作者: xkfxm    时间: 2013-8-15 18:42
  1. InetAddress addr = InetAddress.getByName(null);

  2.                 Socket s = new Socket(addr, 10001);

复制代码
楼主要仔细一点,客户端中获取服务端的IP地址,你传的null,能获取到服务端的IP地址?
显然不能。这样服务端也就接收不到客户端的数据。
所以服务端和客户端都得不到结果
作者: masterV    时间: 2013-8-15 18:50
xkfxm 发表于 2013-8-15 18:42
楼主要仔细一点,客户端中获取服务端的IP地址,你传的null,能获取到服务端的IP地址?
显然不能。这样服务 ...

问题不在这里,这里是没有错误的。通过向getByName()传递一个null,它会默认寻找localhost,并生成特殊的保留地址127.0.0.1(摘自Tinking In Java 4th)。
主要问题在于为什么不能使用BufferedWriter,当使用PrintWriter时就能编译通过。

作者: 吴光新    时间: 2013-8-15 19:23
楼主,你的BUG太多了,
你客户端用的是BufferedWriter,你服务端值读一行,所以你要在bufw.write("hello,server!");后在写一个换行符比如用bufw.newLine(); 添加行结束标记
服务器端呢,你只读一行那么
String str = bufr.readLine();
System.out.println(str);
你这里已经读完一行了,然后你接着在下面再次bufr.readLine()读一行,就没有数据了,除非你用while循环读取,才能读到数据了
所以我把上面那两句注释了,结果运行正确,在客户端打印大写的helloworld
  1. import java.io.*;
  2. import java.net.*;

  3. class TcpClient2
  4. {
  5.         public static void main(String[] args) throws Exception
  6.         {
  7.                 InetAddress addr = InetAddress.getByName(null);
  8.                 Socket s = new Socket(addr, 10001);
  9.                 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
  10.                                 bufw.write("hello,server!");
  11.                                 bufw.newLine();        //添加行结束标记
  12.                 bufw.flush();
  13.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
  14.                
  15.                                 String str = bufr.readLine();
  16.                 System.out.println(str);
  17.                                 bufw.close();
  18.                 s.close();
  19.         }
  20. }

  21. class TcpServer2
  22. {
  23.         public static void main(String[] args) throws Exception
  24.         {
  25.                 ServerSocket ss = new ServerSocket(10001);
  26.                 Socket s = ss.accept();

  27.                 BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
  28.                                 //String str = bufr.readLine();
  29.                                 //System.out.println(str);

  30.                                 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

  31.                                 bufw.write(bufr.readLine().toUpperCase());
  32.                                 bufw.flush();

  33.                                 s.close();
  34.                 ss.close();
  35.                
  36.         }
  37. }
复制代码

作者: 吴光新    时间: 2013-8-15 19:26
本帖最后由 Jiewin 于 2013-8-15 19:30 编辑
魏先勇 发表于 2013-8-15 18:50
问题不在这里,这里是没有错误的。通过向getByName()传递一个null,它会默认寻找localhost,并生成特殊的 ...


不是不能用BufferedWriter,只是BufferedWriter比较麻烦,要写换行和刷新,而在你代码中没有换行标记。

为什么用PrintWriter就可以?,因为用字符打印流可以不用写换行,直接调用println方法就自动完成那两步了。因为它带有换行标记


作者: masterV    时间: 2013-8-15 19:31
Jiewin 发表于 2013-8-15 19:23
楼主,你的BUG太多了,
你客户端用的是BufferedWriter,你服务端值读一行,所以你要在bufw.write("hello,ser ...

恩恩,谢谢斑竹,就是换行的问题,我搞了一下午没弄明白咋回事。{:soso_e113:}

作者: 吴光新    时间: 2013-8-15 19:33
魏先勇 发表于 2013-8-15 19:31
恩恩,谢谢斑竹,就是换行的问题,我搞了一下午没弄明白咋回事。
...

不客气,大家共同学习,问题要是解决了,就改成“已解决”,还不懂可以继续提问





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2