java - 服务器回复客户端消息由于关闭套接字而失败 - Java 客户端-服务器示例

标签 java sockets object client-server

我正在创建这个小客户端-服务器程序来了解套接字,到目前为止,我遇到了一些麻烦。为了这篇文章的目的,我将代码合并到一个类中。并且代码将会编译。 (所以它会显示与我得到的相同的错误)

当客户端连接到服务器时,服务器套接字会在服务器端正确创建套接字。然后,客户端成功向服务器发送消息,但是当服务器尝试向客户端发送响应时,出现错误,表明套接字已关闭。

Main.java

package main;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Hashtable;

public class Main {

    boolean running = true;

    public static void main(String[] args){
        new Main().start();
    }

    public void start(){
        new Thread(new ConnectionListener()).start(); //Starts Server
        try {
            connectToServer();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public class ConnectionListener implements Runnable{    
        public void run() {
            ServerSocket ss = null;

            try {
                ss  = new ServerSocket(31415);
            }catch (BindException e) {
                e.printStackTrace();
                return;
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }

            while(running){
                try {
                    Socket sock = ss.accept();
                    ServerConnection c = new ServerConnection(sock);
                    c.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            try {
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void connectToServer() throws UnknownHostException, IOException{
        //Create Connection to Server
        Socket socket = new Socket("localhost",31415);
        ClientConnection cc = new ClientConnection(socket); 
        cc.start();

        //Send First Message to Server
        Hashtable<Integer, String> htt = new Hashtable<Integer, String>();
        htt.put(0,"Hello, This is a Chat Test");

        Message m = new Message(Message.Type.CHAT,htt);
        cc.sendMessage(m);
    }

    public class ServerConnection{
        Socket sock;
        boolean connected = true;

        public ServerConnection(Socket sock){
            this.sock = sock;
        }

        public void start() {
            new Thread(new RequestListener()).start();
        }

        private void handleMessage(Message m){
            System.out.println("Server : Handle message " + m.type.toString());
        }

        public void disconnect(){
            System.out.println("Disconnect user");
        }

        public void sendMessage(Message m){
                try {
                    ObjectOutputStream os = new ObjectOutputStream(sock.getOutputStream());
                    os.writeObject(m);
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

        class RequestListener implements Runnable{

            public void run() {

                ObjectInputStream is = null;

                try {
                    is = new ObjectInputStream(sock.getInputStream()); 

                    while(connected){
                        try {
                            Message m = (Message)
                                    is.readObject(); //EOFException
                            handleMessage(m);
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }catch(SocketException e){
                            disconnect();
                            e.printStackTrace();
                            break;

                        }catch (IOException e) {
                            //e.printStackTrace();  //EOFException Here
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally{
                    try {
                        is.close();

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public class ClientConnection {

        private Socket socket;
        private boolean connected = true;

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

        public void start(){
            new Thread(new RequestListener()).start();
        }

        public void sendMessage(Message m){
            try {
                ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
                os.writeObject(m);
                os.flush();
                os.close();
            } catch (IOException e) {
                System.out.println("Error Sending Message");
                e.printStackTrace();
            }
        }

        public void close() throws IOException{
            Message m = new Message(Message.Type.DISCONNECT,null);
            sendMessage(m);
            socket.close();
        }

        private void handleMessage(Message m){
            System.out.println("Client : Handle message " + m.type.toString());
        }

        class RequestListener implements Runnable{

            public void run() {

                ObjectInputStream is = null;

                try {

                    System.out.println(socket.isConnected()); //true
                    System.out.println(socket.isClosed()); //false
                    InputStream iss = socket.getInputStream();
                    is = new ObjectInputStream(iss);  //socketClosedException

                    while(connected){
                        try {
                            Message m = (Message)is.readObject();
                            handleMessage(m);
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }catch(SocketException e){

                            System.out.println("Server Disconnected");
                            break;

                        }catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally{
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }   
}

消息.java

package main;

import java.io.Serializable;
import java.util.Hashtable;

public class Message implements Serializable{

    public enum Type{
        LOGIN, PM, DISCONNECT, INCORRECT_LP,CORRECT_LP, UPDATE_USERLIST, CHAT, INCORRECT_VERSION
    }

    public Type type;
    Hashtable ht;

    public Message(Type type, Hashtable ht){
        this.type = type;
        this.ht = ht;
    }

    public Object get(Object o){
        return ht.get(o);
    }
}

最佳答案

没有什么“随机”的。

关闭Socket的输入或输出流会关闭另一个流和Socket。

在这种情况下,您将关闭包裹在套接字输出流周围的ObjectOutputStream,这将关闭该输出流,从而关闭套接字的输入流和套接字。

关于java - 服务器回复客户端消息由于关闭套接字而失败 - Java 客户端-服务器示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16311501/

相关文章:

java - 可以通过我的服务中的套接字发送但无法接收数据

sockets - Netty是否支持通过UNIX域套接字的数据报包?

json - 如何在 Angular 中连接两个对象?

jquery - onClick 不适用于 IE 11 中的单击

javascript - 没有带有 xmlhttprequest 的响应文本

java - 使用扫描仪读取文件时出现空指针异常

Java 将变量传递给映射的 DTO 方法?

C:错误端口上的套接字绑定(bind)

java - 如何从 Java 运行 Linux 脚本

java - Hibernate 中实体特定的监听器/事件/拦截器