【发布时间】:2016-07-22 11:39:40
【问题描述】:
我制作了这个程序,但遇到了问题。当客户端断开连接时,服务器崩溃,我不知道如何解决这个问题。
import java.io.*;
import java.net.*;
public class clientread extends Thread{
Socket sc;
public int ver=0;
public clientread(Socket sc)
{
this.sc=sc;
}
public void run()
{ BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
while(true){
try{
String mes=buf.readLine();
if(mes.equals("END"))
{
sc.close();
break;
}
if(mes!=null)
{
PrintStream ps=new PrintStream(sc.getOutputStream());
ps.println(mes);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
import java.net.*;
import java.io.*;
public class citireserver extends Thread{
Socket sock;
public citireserver(Socket sr)
{
sock=sr;
}
public void run()
{
while(true)
{
try{
BufferedReader buf=new BufferedReader(new InputStreamReader(sock.getInputStream()));
String mes=buf.readLine();
if(mes!=null)
System.out.println(mes);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
第一个从键盘读取消息并将其传输到服务器,服务器将其传输给其余客户端,第二个读取从服务器传输的所有内容并打印。我想在第一类中放置一个条件,如果客户端输入“END”它将终止但不知道结束所有这一切。 这是访问这两个类的客户端类
import java.net.*;
public class client {
public static void disc(Socket sc)
{
try{
sc.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
try{
Socket sr=new Socket("192.168.0.105",1028);
new clientread(sr).start();
new citireserver(sr).start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
import java.net.*;
public class server {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("the server is running");
try{
ServerSocket sr=new ServerSocket(1028,100);
while(true)
{
new handler(sr.accept()).start();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
import java.io.*;
import java.util.*;
import java.net.*;
public class handler extends Thread {
public static ArrayList<Socket> sock=new ArrayList<Socket>();
Socket sc;
public handler(Socket sc)
{
this.sc=sc;
}
public void check()
{
if(!sc.isConnected())
{
for(int i=0;i<sock.size();i++)
if(sock.get(i)==sc)
sock.remove(i);
}
}
public void run()
{
sock.add(sc);
System.out.println("connected");
while(true)
{
try{
BufferedReader io=new BufferedReader(new InputStreamReader(sc.getInputStream()));
String ms=io.readLine();
System.out.println(ms);
if(ms.equals("END"))
{
break;
}
if(ms!=null)
{
Iterator<Socket> it=sock.iterator();
while(it.hasNext())
{
Socket vv=it.next();
PrintStream ps=new PrintStream (vv.getOutputStream());
ps.println(ms);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
try{
sc.close();
check();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
我想把 if 放在 buf.readline 之后的第一个类中,如果条件为真,那么 sc.close 并中断。但它什么也没做,我收到一条消息可能是因为这个套接字在第二类的另一个线程中使用,我不知道如何停止这一切。我在关闭的客户端中收到此错误
java.net.SocketException: 套接字关闭于 java.net.Socket.getInputStream(Socket.java:876) 在 citireserver.run(citireserver.java:15)
编辑:在我用线程解决后,我得到另一个
错误:java.net.SocketException:套接字已关闭 在 java.net.Socket.getOutputStream(Socket.java:916) 在 handler.run(handler.java:41)
在我断开一个客户端后出现此错误,我认为它来自这样一个事实,即该套接字未从数组列表中删除,并且当它迭代时它继续该套接字。为什么它不删除它? check() 有什么问题?
【问题讨论】:
-
你能提供一个堆栈跟踪吗?
-
@user6575913 他的意思是你在控制台中遇到了什么错误?
-
对于现在这样的程序,我没有收到任何错误。我用 ctrl+c 退出客户端,然后服务器程序在无限循环中运行(我不知道为什么)并打印消息“null”
-
如您所见,我没有“END”条件,因为我不知道该放在哪里。在服务器中,我有一个函数可以验证每个套接字是否断开连接并将其从套接字 ArrayList 中删除,但我想我不知道如何断开它以及从哪里断开它。我尝试了多种方法,包括 socket.close 但服务器执行一遍又一遍地做同样的事情。
-
因为你使用的是
while(true)。