当前位置: 首页 > 知识库问答 >
问题:

java套接字聊天代码抛出java.net.SocketException:套接字关闭

尉迟栋
2023-03-14

我尝试用Java套接字API制作基本的Java聊天应用程序。但是当客户端终止时,它会引发以下异常,

socketException:套接字关闭

package com.aaa.server;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class JavaChatServer {

    final static int Port = 10001; 

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ServerSocket serverSocket = null;
        Map<String, PrintWriter> clientMap = null;

        try {
            serverSocket = new ServerSocket(Port);
            clientMap = new HashMap<String, PrintWriter>();
            Collections.synchronizedMap(clientMap);

            while(true) {
                System.out.println("Waiting Connection ....");
                Socket socket = serverSocket.accept();

                ServerThread thread = new ServerThread(socket, clientMap);
                thread.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(!serverSocket.isClosed()) {
                    serverSocket.close();
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

}

class ServerThread extends Thread {
    private Socket socket = null;
    private BufferedReader br = null;

    private Map<String, PrintWriter> clientMap;
    private String id;

    public ServerThread(Socket socket, Map<String, PrintWriter> clientMap) {
        this.socket = socket;
        this.clientMap = clientMap;
    }

    @Override
    public void run() {
        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

            id = br.readLine();
            broadcast(id + " is connected");
            System.out.println("Connected User Id : " + id);
            clientMap.put(id, pw);

            String msg = "";

            while(true) {
                msg = br.readLine();

                if(msg.equals("/exit")) {
                    break;
                }

                broadcast(id + " : " + msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                clientMap.remove(id);
                broadcast(id + " is disconnected!!");

                if (br != null)
                    br.close();
                if(socket != null)
                    socket.close();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    private void broadcast(String msg) throws Exception{
        Collection<PrintWriter> collection = clientMap.values();
        Iterator<PrintWriter> iterator = collection.iterator();

        while(iterator.hasNext()) {
            PrintWriter pw = iterator.next();
            pw.println(msg);
            pw.flush();
        }
    }
}
package com.aaa.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class JavaChatClient {

    final static int Port = 10001;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Socket socket = null;
        PrintWriter pw = null;

        Scanner keyboard = new Scanner(System.in);
        String id = "";

        try {
            socket = new Socket("localhost", Port);

            pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
            System.out.print("Welcome to Chat Room. Pls, type your ID : ");
            id = keyboard.nextLine();
            pw.println(id);
            pw.flush();

            ClientInputThread inputThread = new ClientInputThread(socket);
            inputThread.start();

            String msg = "";
            while (!msg.toLowerCase().equals("/exit")) {
                msg = keyboard.nextLine();

                if(!msg.trim().equals("")) {
                    pw.println(msg);
                    pw.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (keyboard != null)
                    keyboard.close();
                if (pw != null)
                    pw.close();
                if(socket != null)
                    socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

class ClientInputThread extends Thread {
    private Socket socket = null;

    public ClientInputThread (Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br = null;

        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String msg = "";

            while(true) {
                if(socket.isClosed())
                    break;

                msg = br.readLine(); // This line throws SocketException
                System.out.println(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
java.net.SocketException: Socket closed
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at com.aaa.client.ClientInputThread.run(JavaChatClient.java:80)

我认为即使套接字已经关闭,BufferedReader流仍然尝试读取行消息。

但我不知道当客户端终止时,何时以及如何关闭BufferedReader流和套接字连接。

我完全被这部分卡住了。有什么想法吗?

共有1个答案

段干博涉
2023-03-14

这是因为当调用readline()时,socket是关闭的。您可以首先检查msg,如果msg是\exit,那么首先停止inputthread(使用标志或其他东西),然后将\exit发送到服务器。简而言之,检查/exit->停止inputthread->发送/exit到服务器。

String msg = "";
while (!msg.toLowerCase().equals("/exit")) {
    msg = keyboard.nextLine();

    if (msg.toLowerCase().equals("/exit")) {
        // stop inputThread.
        // make sure inputThread is stopped.
    }

    if (!msg.trim().equals("")) {
        pw.println(msg);
        pw.flush();
    }
}
 类似资料:
  • 我正在为客户机发送对象到服务器,在服务器端修改该对象,并将其重新发送到客户机。将对象从客户机发送到服务器很好,它工作正常,但当我将对象发送回来时,它给出了异常,Socket关闭。这里是代码。IntString和ParentObj是我要发送对象的类。 服务器类 用于发送和接收对象的Send_recv类。

  • 我最近一直在玩套接字,但是我遇到了一个问题…当我从服务器接收数据时,我得到一个“java.net.套接字异常:套接字关闭”异常。我没有在任何地方关闭套接字,事实上,我唯一使用关闭()的地方是扫描仪上从System.in读取文本; 以下是我的代码: 客户: 服务器: 数据包发送者: 客户端接收器: 数据包接收器:

  • 我想创建能够与多个客户端连接的服务器,但我总是收到“套接字关闭”异常或从输入流中读取空值,以前我认为这是由于以错误的方式关闭套接字连接引起的,所以我发布了这个主题,但现在似乎这不是问题所在。 服务器方法 HandlerThread类 客户端模拟器 例外和问题 在客户端模拟器之前启动服务器,客户端模拟器没有任何异常,但是在服务器端,并没有收到所有数据,从控制台打印信息时,我看到“null”、“Hel

  • 我有一个硬件设备,我用TCP/IP与它通信。 您能对Windows或Java或任何其他导致此问题的相关设置进行映像吗?

  • 我正在使用socket在Python3中创建一个简单的聊天 这是密码 客户 服务器 当用户连接时,如何向服务器打印字符串? 在您插入名称后,我尝试添加此字符串 但对我来说,输出是不可靠的 另一个问题:为什么我在发送消息时会得到这样的东西?

  • 线程“main”java.net.ConnectException:连接超时:在java.net.dualStackplainsockeTimpl.Connect0(本机方法)在java.net.dualStackplainsockeTimpl.socketConnect(DualStackplainsockeTimpl.java:69)在java.net.abstractplainsockeTi