PrintWriter.close()不调用会泄露资源吗?

深山老宅 2008-04-08 02:52:49
public void send(Socket ss,String str)
{
PrintWriter out=null;
try
{
out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(ss.getOutputStream())));
if(str!=null)
{
out.println(str);
out.flush();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
/*finally
{
try{
if(out!=null)
out.close();
}catch(Exception e){}
}*/
}
当我把上面代码中 finally部分写上时,程序编译没错,运行一会后报错:socket closed!
不写finally{}运行正常.
问题:
1.不写会不会泄露资源?不是应该调用close()方法吗?
2.关闭out会导致把socket也关掉吗?
...全文
628 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
haoxiongok 2008-04-10
  • 打赏
  • 举报
回复
顶楼主
shili150 2008-04-10
  • 打赏
  • 举报
回复
socket
不懂编程 2008-04-10
  • 打赏
  • 举报
回复
ding主楼
hmsuccess 2008-04-09
  • 打赏
  • 举报
回复
mark
云上飞翔 2008-04-09
  • 打赏
  • 举报
回复
答(继续)而你的原来的设计最大的不好之处是:线程中创建了InputStream流,进行读.而OutputStream流恰恰又在线程之外不断创建与关闭(每转发一次,同一个Socket对象的OutputStream流就要创建与关闭一次),通信结束,Socket对象又在线程之外被不知道被谁关闭.这才是问题的主要根源.

以上意见仅供你参考
云上飞翔 2008-04-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhaiminlove 的回复:]
现将程序贴下,程序目的:建立一C/S系统,实现当某个client向服务器发消息,服务器将次消息转发给所有的client;当client打下/list字符串时
只有本client会获得所有的client的IP,即服务器不向其他人发送。
以下为服务程序。(不会是我的程序结构设计错了吧,导致我“不close()泄露资源,调用了又会关闭ss”)
import java.net.*;
import java.io.*;
import java.ut…
[/Quote]
答:我的以下意见仅供你参考:
你的程序的目的,我已清楚.根据这个目的,我认为,你的程序结构在设计时有比较大的不妥,所以才有你的这个问题.
我想,结构能否如下设计:
1)每一个客户,对应服务器方的一个线程.也只有这个线程才知道如何与它的客户进行通信.或都说,与这个客户进行通信的信息都委托给这个线程来进行.基于这一个考虑,LinkedList arrList存放的不是Socket对象,而是线程.
2)每一个线程全权自己管理自己的与它的客户的网络通信,故,当线程创建并启动后,由线程进行网络流的I/O.当通信结束时,由线程进行流的关闭,并关闭它的Socket对象.
3)每一个线程向外界开放一个方法:send(String msg),用于自己及其它人通过该方法,向本线程的客户发送(或转发)信息.
4)arrList是一个临界区,至少开放两个方法:一个用于线程将自己加入到arrList中.另一个用于当线程通过结束要关闭之前,将自己从arrLIst中删除.而broadcast(String str) 功能则用于依次遍历arrList,对其中的每一个线程调用它的send(str)即可.
a15664153 2008-04-09
  • 打赏
  • 举报
回复
那你把流对象作为一个类成员吧,在socket实例化后初始化该对象,到最后认为连接该结束的时候再关闭.
深山老宅 2008-04-09
  • 打赏
  • 举报
回复
现将程序贴下,程序目的:建立一C/S系统,实现当某个client向服务器发消息,服务器将次消息转发给所有的client;当client打下/list字符串时
只有本client会获得所有的client的IP,即服务器不向其他人发送。
以下为服务程序。(不会是我的程序结构设计错了吧,导致我“不close()泄露资源,调用了又会关闭ss”)
import java.net.*;
import java.io.*;
import java.util.LinkedList;

public class Server
{
ServerSocket ss;
Socket s;

static LinkedList arrList=new LinkedList(); //用来存储所有连接到服务器的socket(客户)

public Server() throws Exception{
ss=new ServerSocket(2345);

}
public static LinkedList getList()
{
refresh();
return arrList;
}
public void init() throws Exception{
while(true){
s=ss.accept();
System.out.println("Server listening...");
arrList.add(s); //有刚连接的socket,将之加到arrList
new MyThread((Socket)s).start(); //为每一个连接到服务器的客户创建一个线程
}
}
public static void refresh() //更新arrList(去掉断开的连接)
{
for(int i=arrList.size();i>0;i--)
{
if(((Socket)arrList.get(i-1)).isClosed())
arrList.remove(i-1);
}
}


public static void main(String[] args) throws Exception
{
Server s=new Server();
s.init();
}
}

class MyThread extends Thread{
Socket s;

public MyThread(Socket s) //将刚创建的Socket传到专门处理它的thread
{
this.s=s;
}

public void run()
{

BufferedReader br=null;
try{

br =new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true)
{
String temp=br.readLine();
if(temp.startsWith("/list"))
ListTheList();
else
broadcast("message from "+s.getInetAddress()+":\t"+temp);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
try
{

if(br!=null)
br.close();
}catch(Exception e){}
}

}
public void broadcast(String str)
{
LinkedList LL=Server.getList();

for(int i=0;i<LL.size();i++)
{
send(((Socket)LL.get(i)),str);
}

}
public void ListTheList() //列出所有的client
{
LinkedList LL=Server.getList();
StringBuffer sb=new StringBuffer();

if(LL.size()!=0){
for(int i=0;i<LL.size();i++)
{
sb.append(((Socket)LL.get(i)).getInetAddress()+"is in the list\n");
}
send(s,sb.toString());
}
}
public void send(Socket ss,String str)//向连接ss发送 str
{
PrintWriter out=null;
try
{
out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(ss.getOutputStream())));
if(str!=null)
{
out.println(str);
out.flush();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
/*finally
{
try{
if(out!=null)
out.close();
}catch(Exception e){}
}*/
}
}
云上飞翔 2008-04-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhaiminlove 的回复:]
但是实际证明:我关闭out,随之就socket closed!
上面的send()函数将被其他函数调用,ss在被send()用过后我想在后面继续使用ss;
不close()泄露资源,调用了又会关闭ss,我将何去何从?

out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(ss.getOutputStream())));
out到底与ss是什么关系?
[/Quote]
答:“ss在被send()用过后我想在后面继续使用ss”;对于TCP不是重复使用socket,而应重复使用它所关联的
gjgj3368 2008-04-08
  • 打赏
  • 举报
回复
1,应该关
2,会
momo1985 2008-04-08
  • 打赏
  • 举报
回复
就好象打电话一样啊,关了out就等于挂断了,所以如果你不想关闭socket就别关out
深山老宅 2008-04-08
  • 打赏
  • 举报
回复
但是实际证明:我关闭out,随之就socket closed!
上面的send()函数将被其他函数调用,ss在被send()用过后我想在后面继续使用ss;
不close()泄露资源,调用了又会关闭ss,我将何去何从?

out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(ss.getOutputStream())));
out到底与ss是什么关系?
云上飞翔 2008-04-08
  • 打赏
  • 举报
回复
答:
1)要调用out.close()操作,这是个好习惯。否则可能会“泄漏资源”。
2)只有当你认为通信全部结束,不需要数据交换时,再去:先关闭流,然后关闭socket.

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧