帮忙看看我写的这小练习程序哪里出错了。。客户端一发送消息就报EOFException 
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at com.taoyongming.ChatV2.ChatServer$RecvThread.recv(ChatServer.java:86)
at com.taoyongming.ChatV2.ChatServer$RecvThread.run(ChatServer.java:77)
at java.lang.Thread.run(Unknown Source)
与客户端通信异常
package com.taoyongming.ChatV2;import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
/*
 * J2SE 练习 聊天小程序雏形 
 */
public class ChatServer extends JFrame {
private ServerSocket ss;
private TextArea ta = new TextArea();
private java.util.List<RecvThread> threads = new ArrayList<RecvThread>();

//产生服务器程序的图形界面方法
public void launchFrame() {
setBounds(100,50,500,600);
setVisible(true);
add(ta,BorderLayout.CENTER);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

//构造方法 初始化一些 用来获得端口号参数,创建监听端口,调用图像界面方法
public ChatServer(int port) {
try {
ss = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器未成功启动");
}
launchFrame();
}

//启动服务器的方法,在此方法中等待接受客户端连接请求,并将接下来的通信过程交由单独线程来做
public void startServer() {
while (true) {
try {
Socket s  = ss.accept();
RecvThread rt =  new RecvThread(s);
threads.add(rt);
ta.append("A Client Connect! Client IP: " + s.getInetAddress() + 
"Client Port: " + s.getPort()  + "在线总人数 : " + threads.size());
ta.append("\n");
Thread thread = new Thread(rt);
thread.start(); //起一个线程用来和一个客户端通信
} catch (IOException e) {
e.printStackTrace();
System.out.println("接收客户端连接请求失败");
}
}
}
//得到与客户端通信的socket后调用此线程内部类,用于和线程通信
private class RecvThread implements Runnable {
DataOutputStream dos;
Socket s;
InputStream is;
DataInputStream dis;
//构造方法 接受socket 
public RecvThread(Socket s) {
this.s=s;
}
//线程的run方法,与客户端通信 用于处理接受信息 及 发送信息和 通信关闭的处理
public void run() {
try {
is = s.getInputStream();//获得与客户端通信的输入流
dis = new DataInputStream(is);//获得基本数据类型的输入流
} catch (IOException e) {
e.printStackTrace();
System.out.println("与客户端通信异常");
}
String str =recv();
while(str !=null && str.length()!=0) {//循环接收和发送的过程,判断条件接收到不为空的字符串时 做循环
sendAllClient(str);
str =recv();
}

dispose();//循环结束 表示客户端与客户端失去正常通信,关闭资源
}

//接受客户端信息
public String recv() {
try {
String str =dis.readUTF();//读取一个字符串
System.out.println(str);
return str;
} catch (IOException e) {
e.printStackTrace();
System.out.println("与客户端通信异常");
return "";
}

}
//把接受到的信息发送给与此线程对象通信的客户端,由sendAllClient调用
public void send(String rev) {
try {
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(rev);
} catch (IOException e) {
e.printStackTrace();
System.out.println("与客户端通信异常");
}
}
// 接收到客户端信息之后,调用此方法,遍历所有的线程对象,把信息发给各个线程通信的客户端
public void sendAllClient(String rev) {
for(Iterator<RecvThread> it = threads.iterator(); it.hasNext();) {
RecvThread rt = it.next();
rt.send(rev);
}
}
//在调用此方法前 先判断出和客户端失去连接,之后调用此方法处理关闭资源等功能
public void dispose() {
if(s != null) {
try {
s.close();
threads.remove(this);
ta.append("A Cilent out" + "在线人数 :" + threads.size() + "\n");
} catch (IOException e) {
e.printStackTrace();
this.dispose();
}
}
}
}
public static void main(String[] args) {
new ChatServer(5000).startServer();
}
}package com.taoyongming.ChatV2;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;import javax.swing.*;
public class ChatClient extends JFrame{
private Socket s;
private JTextArea ta;
private JTextField tf;
private static int count=0;
private int id;
//构造函数初始化图像界面
public  ChatClient() {
count++;
launchFrame();
id = count;
}
//构建客户端图形界面
public void launchFrame() {
this.setBounds(950, 50, 260, 400);
setBackground(Color.ORANGE);
ta = new JTextArea();
tf = new JTextField();
add(ta,BorderLayout.CENTER);
add(tf,BorderLayout.SOUTH);
setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tf.addKeyListener(new KeyMonitor());
}
//处理键盘事件的监听类,用于处理textfield的键盘事件
class KeyMonitor extends KeyAdapter {
OutputStream os;
DataOutputStream dos;
public void keyPressed(KeyEvent e) { 
//当接收到键盘的回车按键输入事件的时候,读取一行字符串显示在textarea中,并发送个服务器
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
String str =tf.getText();
System.out.println(id +" : "+ str);
ta.append(str + "\n");
send(str);
tf.setText("");
}
}
//按回车后调用,把信息发送给客户端
public void send(String str){
try {
os = s.getOutputStream();//得到输出流
dos = new DataOutputStream(os);
dos.writeUTF(id + ":" + str);
} catch (IOException e1) {
e1.printStackTrace();
System.out.println("数据传输失败");
}
}
}
//启动客户端的主业务逻辑方法,当与服务器建立连接后,新建一个线程用于接收服务器的数据
public void clientStart(String ip, int port) {
try {
s = new Socket(ip,port); //发送连接服务器请求
new Thread(new RevServer()).start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("连接服务器失败");
e.printStackTrace();
}
}
//线程类 用于处理客户端与服务器建立连接后 接收服务器的信息
private class RevServer implements Runnable {
public void run() {
if(s == null) return;
String str =recv();
while(str != null && str.length() !=0) {
ta.append(str + "\n");
str = recv();

disconnect();
}
//线程启动后,接收服务器信息的并打印到textArea
public String recv() {
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
String str = dis.readUTF();
}catch (IOException e) {
e.printStackTrace();
System.out.println("接受信息失败");
}return "";
}
}
//关闭客户端资源,当结束客户端连接时调用
public void disconnect() {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
disconnect();
}
System.exit(-1);
}
public static void main(String[] args) {
new ChatClient().clientStart("127.0.0.1",5000);
}
}

解决方案 »

  1.   

    private class RevServer implements Runnable {
    public void run() {
    if (s == null)
    return;
    String str = recv();
    while (str != null && str.length() != 0) {
    ta.append(str + "\n");
    str = recv();
    }
    disconnect();
    }
    找到上面的代码了么;
    每次发送消息后都会执行:
    disconnect();导致你客户端直接关闭,而服务端还在读客户端的数据,导致了EOFException
      

  2.   

    直接原因其实是
    recv() 方法每次都返回空串,导致了while不执行
      

  3.   

    ChatServer里面run()方法有错,没取到值,改用BufferedReader试试
      

  4.   


    实际上是因为客户端关闭了才没取到值。 他的这个取值方法是可以的,BufferedReader只是更好而已,没有对错。
      

  5.   

    的确是这问题,
    return“”; 应该放在catch里面的,搞了半天原来就是这么个小问题。。