黑马程序员技术交流社区

标题: 线程间关闭流 [打印本页]

作者: 张森    时间: 2013-1-3 04:22
标题: 线程间关闭流
我写了个TCP的服务端和客户端  我用的是BufferedWriter缓冲流  他们在传输的时候必须要执行bw.newLine()和bw.flush();这个我能理解。
问题:
1、但为什么 bw.write("")和bw.newLine()和bw.flush()必须紧挨着写 哪怕我在中间随便打印一个System.out.println(""),那么都会导致缓冲区的根本就没有flush呢?
2、请大家看看下面的程序 我在服务器端和客户端都判断了"quit",其实这个只在客户端执行了,我的问题是 ,当我客户端判断从控制台输入的是quit的时候,我在客户端关闭了相应的流和socket。那么我在服务器端对应的流和socket他们也关闭了吗。 请大家最好用代码来说明这个问题。
  1. <blockquote><div class="blockcode"><div class="blockcode">package cn.itcast;</div><div class="blockcode">
  2. </div><div class="blockcode">import java.io.BufferedReader;</div><div class="blockcode">import java.io.BufferedWriter;</div><div class="blockcode">import java.io.IOException;</div><div class="blockcode">import java.io.InputStream;</div><div class="blockcode">import java.io.InputStreamReader;</div><div class="blockcode">import java.io.OutputStream;</div><div class="blockcode">import java.io.OutputStreamWriter;</div><div class="blockcode">import java.io.PrintWriter;</div><div class="blockcode">import java.io.StringWriter;</div><div class="blockcode">import java.net.ServerSocket;</div><div class="blockcode">import java.net.Socket;</div><div class="blockcode">import java.nio.charset.Charset;</div><div class="blockcode">import java.util.Scanner;</div><div class="blockcode">
  3. </div><div class="blockcode">public class ServerTest {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>public static void main(String[] agrs) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>ServerSocket ss = null;</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>try {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>ss = new ServerSocket(8000);</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>} catch (IOException e) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>e.printStackTrace();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>while (true) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>Socket s = null;</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>try {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>s = ss.accept();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>System.out.println(s.getInetAddress()+"我链接上来了");</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>} catch (IOException e) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>e.printStackTrace();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>new Thread(new ServiceTotal(s)).start();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="blockcode">}</div><div class="blockcode">
  4. </div><div class="blockcode">class ServiceTotal implements Runnable {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>private Socket s;</div><div class="blockcode">
  5. </div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>public ServiceTotal() {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="blockcode">
  6. </div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>public ServiceTotal(Socket s) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>this.s = s;</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="blockcode">
  7. </div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>public void run() {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>try {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>InputStream in = s.getInputStream();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>OutputStream out = s.getOutputStream();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>BufferedReader bf = new BufferedReader(new InputStreamReader(in));</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>String str = null;</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>while((str = bf.readLine())!=null){</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>if(bf.equals("quit")){</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                        </span>destroy(s, bf, bw);</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                        </span>break;</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>System.out.println("来自"+s.getInetAddress()+"客户端的信息-----"+ str);</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>bw.write(new StringBuffer(str).reverse().toString());</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>bw.newLine();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                                </span>bw.flush();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>} catch (IOException e) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>e.printStackTrace();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class="blockcode">
  8. </div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>public static void destroy(Socket s,BufferedReader br,BufferedWriter bw){</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>try {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>br.close();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>bw.close();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>s.close();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>} catch (IOException e) {</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                        </span>e.printStackTrace();</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">                </span></div><div class="blockcode"><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="blockcode">}</div></div><div>
  9. </div>
复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {
        public static void main(String[] args) {
                Socket s = null;
                InputStream in = null;
                OutputStream out = null;
                BufferedReader br = null;
                BufferedWriter bw = null;
                try {
                        s = new Socket("127.0.0.1", 8000);
                        String str = null;
                        Scanner scanner = new Scanner(System.in);
                        while ((str = scanner.nextLine())!=null) {
                                if(str.equals("quit")){
                                        destroy(s,br,bw,scanner);
                                        break;
                                }
                                in = s.getInputStream();
                                out = s.getOutputStream();
                                br = new BufferedReader(new InputStreamReader(in));
                                bw = new BufferedWriter(new OutputStreamWriter(out));
                                bw.write(str);
                                bw.newLine();
                                bw.flush();
                                System.out.println("来自服务器"+s.getInetAddress()+"的消息"+br.readLine());
                               
                        }
                       
                } catch (UnknownHostException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
        public static void destroy(Socket s,BufferedReader br,BufferedWriter bw,Scanner scanner){
                try {
                        br.close();
                        bw.close();
                        s.close();
                        scanner.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }
               
        }
}











作者: 张森    时间: 2013-1-3 04:24
我晕死 不好意思刚刚出问题了 重发服务器端的代码

package cn.itcast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.Scanner;

public class ServerTest {
        public static void main(String[] agrs) {
                ServerSocket ss = null;
                try {
                        ss = new ServerSocket(8000);
                } catch (IOException e) {
                        e.printStackTrace();
                }
                while (true) {
                        Socket s = null;
                        try {
                                s = ss.accept();
                                System.out.println(s.getInetAddress()+"我链接上来了");
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                        new Thread(new ServiceTotal(s)).start();
                }
        }
}

class ServiceTotal implements Runnable {
        private Socket s;

        public ServiceTotal() {
        }

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

        public void run() {
                try {
                        InputStream in = s.getInputStream();
                        OutputStream out = s.getOutputStream();
                        BufferedReader bf = new BufferedReader(new InputStreamReader(in));
                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
                        String str = null;
                        while((str = bf.readLine())!=null){
                                if(bf.equals("quit")){
                                        destroy(s, bf, bw);
                                        break;
                                }
                                System.out.println("来自"+s.getInetAddress()+"客户端的信息-----"+ str);
                                bw.write(new StringBuffer(str).reverse().toString());
                                bw.newLine();
                                bw.flush();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }

        }
        public static void destroy(Socket s,BufferedReader br,BufferedWriter bw){
                try {
                        br.close();
                        bw.close();
                        s.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }
               
        }
}
作者: 张森    时间: 2013-1-3 04:41
OK自己搞定  上面的程序写得不够健壮
当客户端突然断电没告诉服务器关闭的时候  服务器端是不会关闭socket和流的
但我们要在服务器端捕捉异常  当捕捉到异常的时候   然后再把服务器端的socket和流关闭




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