A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 段波 黑马帝   /  2011-12-3 22:53  /  2741 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 段波 于 2011-12-7 12:53 编辑

public class Servicer implements Runnable{
                Socket s;

                public Servicer(Socket s) {
                        this.s = s;
                }

                public void run() {
                       
                        try {
                                InputStream ips= s.getInputStream();
                                OutputStream ops= s.getOutputStream();
                                BufferedReader br= new BufferedReader(new InputStreamReader(ips));
                                DataOutputStream dos= new DataOutputStream(ops);
                                while(true){
                                        String str=br.readLine();
                                        if(str.equalsIgnoreCase("quit")){
                                                System.out.println("The Client has been out !");
                                                break;
                                               
                                        }
                                        String strBack=str.toUpperCase();
                                        dos.writeBytes(strBack);
                                        br.close();
                                        dos.close();
                                        s.close();
                                }
                        } catch (IOException e) {
                               
                                e.printStackTrace();
                        }
                        }
}

public class TcpServer {

        public static void main(String[] args) {
                try {
                        ServerSocket ss= new ServerSocket(8000);
                        while(true){
                                Socket s=ss.accept();
                                new Thread(new Servicer(s)).start();
                               
                               
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
               
                        }
}
public class TCPClient {
        public static void main(String[] args) {
        try {
                Socket s= new Socket(InetAddress.getByName("172.16.9.115"),8000);
                InputStream ips=s.getInputStream();
                OutputStream ops= s.getOutputStream();
                BufferedReader brKey= new BufferedReader(new InputStreamReader(System.in));
                DataOutputStream dos= new DataOutputStream(ops);
                BufferedReader brNet= new BufferedReader(new InputStreamReader(ips));
                while(true){
                        String str= brKey.readLine();
            dos.writeBytes(str+System.getProperty("line.separator"));
                        if(str.equalsIgnoreCase("quit")){
                                break;
                                }else
                                {
                                        System.out.println(brNet.readLine());
                                       
                                }
                         
                        }
                   dos.close();
                   brKey.close();
                   brNet.close();
                   s.close();
               
        } catch (Exception e) {
                e.printStackTrace();
        }
               
        }
}
请问为什么客户端和服务端只能通信一次,客户端还没退出就自己死掉了呢?有时还返回null

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

5 个回复

倒序浏览
想要多通信几次的话,就要用到循环,一直等待客户端的输入
回复 使用道具 举报
要用到while()的
回复 使用道具 举报
在service端,你将关闭的通道代码写在了while循环内,当然执行一次后,链接就被断开,同时,service端和Client端你都使用的是readLine()方法,该方法是阻塞式的,你在Client写了结束标记(System.getProperty("line.separator")),但在service端却没用写,因加上。
回复 使用道具 举报
本帖最后由 刘海涛 于 2011-12-5 13:49 编辑

你这段代码好多错误,我修改了下,你可以复制运行。
1.close() 关闭的地方不对,应该是在程序结束才关闭,不应该放在循环,所以导致你的刚连接上发信息就退出。
2. 服务器回写客户端的时候也应该加System.getProperty("line.separator")。
3.  Client  用了两次读取 导致也无法打印,使得程序阻塞,打印的应该是服务器回显的。大写。
String str= brKey.readLine();
   dos.writeBytes(str+System.getProperty("line.separator"));
              if(str.equalsIgnoreCase("quit")){
             break;
             }else
      {
             System.out.println(brNet.readLine());
     }
具体解决方案见下面代码。

4 资源关闭前应该判断是否为空,否则抛空指针异常。
  1. import java.io.IOException;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;

  4. public class TcpServer {

  5.         public static void main(String[] args) {
  6.                 try {
  7.                         ServerSocket ss = new ServerSocket(8000);
  8.                         while (true) {
  9.                                 Socket s = ss.accept();
  10.                                 new Thread(new Servicer(s)).start();
  11.                         }
  12.                 } catch (IOException e) {
  13.                         e.printStackTrace();
  14.                 }
  15.         }
  16. }





  17. import java.io.BufferedReader;
  18. import java.io.DataOutputStream;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.InputStreamReader;
  22. import java.io.OutputStream;
  23. import java.net.Socket;

  24. public class Servicer implements Runnable {
  25.         Socket s;

  26.         public Servicer(Socket s) {
  27.                 this.s = s;
  28.         }

  29.         public void run() {
  30.                 BufferedReader br = null;
  31.                 DataOutputStream dos = null;
  32.                 try {
  33.                         InputStream ips = s.getInputStream();
  34.                         OutputStream ops = s.getOutputStream();
  35.                         br = new BufferedReader(new InputStreamReader(ips));
  36.                         dos = new DataOutputStream(ops);
  37.                         while (true) {
  38.                                 String str = br.readLine();
  39.                                 if (str.equalsIgnoreCase("quit")) {
  40.                                         System.out.println("The Client has been out !");
  41.                                         break;
  42.                                 }
  43.                                 String strBack = str.toUpperCase();
  44.                                 System.out.println(strBack);
  45.                                
  46.                                 dos.writeBytes(strBack +  System.getProperty("line.separator"));
  47.                                 dos.flush();

  48.                         }
  49.                 } catch (IOException e) {
  50.                         e.printStackTrace();
  51.                 } finally {
  52.                         try {
  53.                                 if (br != null) {
  54.                                         br.close();
  55.                                 }
  56.                                 if (dos != null) {
  57.                                         dos.close();
  58.                                 }
  59.                                 if (s != null) {
  60.                                         s.close();
  61.                                 }
  62.                         } catch (IOException e1) {
  63.                                 e1.printStackTrace();
  64.                         }
  65.                 }
  66.         }
  67. }



  68. import java.io.BufferedReader;
  69. import java.io.DataOutputStream;
  70. import java.io.IOException;
  71. import java.io.InputStream;
  72. import java.io.InputStreamReader;
  73. import java.io.OutputStream;
  74. import java.net.InetAddress;
  75. import java.net.Socket;

  76. public class TCPClient {
  77.         public static void main(String[] args) {
  78.                 BufferedReader brKey = null;
  79.                 DataOutputStream dos = null;
  80.                 BufferedReader brNet = null;
  81.                 Socket s = null;
  82.                 try {
  83.                         s = new Socket(InetAddress.getByName("127.0.0.1"), 8000);
  84.                         InputStream ips = s.getInputStream();
  85.                         OutputStream ops = s.getOutputStream();
  86.                         brKey = new BufferedReader(new InputStreamReader(System.in));
  87.                         dos = new DataOutputStream(ops);
  88.                         brNet = new BufferedReader(new InputStreamReader(ips));
  89.                         while (true) {
  90.                                 String str = brKey.readLine();
  91.                                 dos.writeBytes(str + System.getProperty("line.separator"));
  92.                                 if (str.equalsIgnoreCase("quit")) {
  93.                                         break;
  94.                                 }  
  95.                                 dos.flush();
  96.                                 System.out.println(brNet.readLine());
  97.                         }
  98.                 } catch (Exception e) {
  99.                         e.printStackTrace();
  100.                 } finally {
  101.                         try {
  102.                                 if (dos != null) {
  103.                                         dos.close();
  104.                                 }
  105.                                 if (brKey != null) {
  106.                                         brKey.close();
  107.                                 }
  108.                                 if (brNet != null) {
  109.                                         brNet.close();
  110.                                 }
  111.                                 if (s != null) {
  112.                                         s.close();
  113.                                 }
  114.                         } catch (IOException e1) {
  115.                                 e1.printStackTrace();
  116.                         }
  117.                 }

  118.         }
  119. }
复制代码

评分

参与人数 1技术分 +2 收起 理由
admin + 2 很热心的童鞋!

查看全部评分

回复 使用道具 举报
楼主的问题应该是出在客户端和服务端都在等待,因为都有阻塞式方法readLine(),导致两端都在等待,比如客户端向服务端发送中并只是把回车符之前的发送给服务端,服务端没收到结束标志,导致停在那了,应该客户端 dos.writeBytes(str+System.getProperty("line.separator"));String str= brKey.readLine();再加上写过去换行。同样在服务端中也没有回车符的结束标志,也应该在dos.writeBytes(strBack);后再加换行符写过去给客户端。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马