收藏 关于socket使用setSoTimeout后出现的问题(服务器老是不间断的向客户端发送消息)

xiaomm627 2013-01-30 08:49:19
服务端:

//服务端
package test;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;


public class Server extends Frame implements ActionListener
{
TextArea ta=new TextArea( );
Panel panel=new Panel( );//创建面板对象
ServerSocket server;
OutputStream out = null;


public Server(){
super("服务器");
setSize(300,180);
this.setLocation(300,300);
add("North",panel);//在窗体上添加面板
add("Center",ta);//在窗体上添加文本区
addWindowListener(new WindowAdapter( ){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
setVisible(true);


try{
server =new ServerSocket(5555);
}
catch(IOException ioe){ }

while(true){
try{
Socket client=server.accept( );
ta.append("\n发现新的客户机连接:"+client.getInetAddress( ).getHostName( ));
new receiveToClientThread(client,ta).start();
}
catch(IOException ioe){ }
}
}
public static void main(String args[ ]){
new Server( );
}
@Override
public void actionPerformed(ActionEvent arg0) {

}


}


class receiveToClientThread extends Thread{
Socket client;
InputStream in;
TextArea ta=new TextArea( );
public receiveToClientThread(Socket client,TextArea ta){
this.client = client;
try {
in = client.getInputStream( );
} catch (IOException e) {
e.printStackTrace();
}

try {
this.client.setSoTimeout(5000);
} catch (SocketException e) {
}
this.ta = ta;
}

public void run(){

while(true){
byte[ ] buff=new byte[512];//缓冲数组
try {
in.read(buff);
String str;
try {
str = new String(buff,"utf-8");
ta.append("\n"+str);//接受客户端发送的数据包
} catch (UnsupportedEncodingException e) {}

}catch(SocketTimeoutException ste){
ste.printStackTrace();
try {
client.close();
in.close();
} catch (IOException e1) {
e1.printStackTrace();
break;
}

break;

}
catch (IOException e) {
e.printStackTrace();
break;
}

}
}

}




客户端:
//客户端程序
package test;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;

public class Client extends Frame implements ActionListener{
Label label=new Label("向服务器发送信息");
TextField tf= new TextField(20);
TextArea ta=new TextArea( );
Panel panel=new Panel( );//创建面板对象

Socket Client;
InputStream DataIn;
OutputStream DataOut;

public Client( ){
super("客户端");
setSize(300,180);
this.setLocation(500,300);
panel.add(label);//在面板上添加标签
panel.add(tf);//在面板上添加文本框
tf.addActionListener(this);//注册
add("North",panel);//在窗体上添加面板
add("Center",ta);//在窗体上添加文本区
addWindowListener(new WindowAdapter( )
{ public void windowClosing(WindowEvent e)
{ System.exit(0);}});
setVisible(true);

try{
Client=new Socket();
Client.connect(new InetSocketAddress("localhost",5555), 2000);//建立连接超时设置

ta.append("成功连接至服务器:"+Client.getInetAddress( ).getHostName( ));
DataIn=Client.getInputStream( );
DataOut=Client.getOutputStream( );
}
catch(IOException ioe){ }
while(true){
try{
byte buff[ ]=new byte[1024*1024];//缓冲数组
DataIn.read(buff);
String str=new String(buff);//接受服务器端发送的数据包
ta.append("\n服务器返回消息:"+str);
}catch(IOException ioe){ }
}
}


public void actionPerformed(ActionEvent e){//事件处理程序
try{
String str=new String(tf.getText().trim());
byte buf[ ]=str.getBytes( );
tf.setText(" ");
DataOut.write(buf);
ta.append("\n客户机发送消息:"+str);
}catch(IOException ioe){ }
}

public static void main(String args[ ]){
new Client( );
}

}


在服务端,每接收一个客户机连接就开辟一个线程执行相关任务。 每个连接到服务器的线程都设置一个超时时间(这个超时时间指的是一定之间内客户机没有数据发过来服务器就断开与此客户机的连接并销毁当前连接资源)setSoTimeout

在线程体里捕捉SocketTimeoutException异常:

catch(SocketTimeoutException ste){
ste.printStackTrace();
try {
client.close();
in.close();
} catch (IOException e1) {
e1.printStackTrace();
break;
}

break;

}


我的意思是一旦超时连接就关闭连接资源,销毁当前线程。可是运行程序的时候你们会发现,当捕捉到SocketTimeoutException后,服务器就会不间断的向客户机发送空消息,客户端的界面上不断的刷新来自服务器的消息。 后来我发现只要 client.close();就会出现这种情况。。 我不明白为什么client.close就会出现上述异常。我想实现一旦超时就关闭连接资源,怎么实现。 求助。
...全文
80 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

62,621

社区成员

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

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