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

JavaObjectInputStream(Socket套接字)重启整个应用程序?

公良琛
2023-03-14

所以我要做一个java服务器和客户端。

目前,我的客户端连接到服务器,并为客户端和服务器端创建对象输入和输出流。

当我试图通过服务器的ObjectInputStream(套接字)接收数据时,它会立即重新启动整个程序。

它甚至没有提到任何错误或例外或其他?客户端表示:"服务器已关闭连接:java.net.SocketExcture:套接字已关闭"

这是我的服务器和客户端(额外问题:如果服务器和客户端中有不同的命名对象,但这些对象的制作方式相同,我可以通过套接字发送和读取它们吗?)

package com.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.gui.Screen;
import com.gui.TextArea;

public class Server implements Runnable{
//Every connection got their own unique id
private static int uniqueId;
//List all the clients
private static ArrayList<ClientThread> al;
private static boolean running = false;
@SuppressWarnings("unused")
private SimpleDateFormat sdf;
ServerSocket serverSocket;

public Server(int port) {
    sdf = new SimpleDateFormat("HH:mm:ss");
    al = new ArrayList<ClientThread>();
}

public void run() {
    running = true;
    try {
        serverSocket = new ServerSocket(Screen.portnumber);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        //Server socket
        TextArea.AddLine("Server is running and waiting for Clients to connect.");
        while(running){
            Socket socket = serverSocket.accept();
            ClientThread t = new ClientThread(socket);
            al.add(t); //saving new client to our arraylist.
            t.run();
            if(!running){ //this will make server running stop.
                TextArea.AddLine("Closing the server..");
                break;
            }
        }
        for(int i = 0; i< al.size(); i++){//We forget about all the clients.
            //Maybe also save all the data here?
            ClientThread tc = al.get(i);
            try{
            tc.sInput.close();
            tc.sOutput.close();
            tc.socket.close();
            }
            catch(IOException ioE){

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

public static void close() {
    running = false;
    try {
        new Socket("localhost", Screen.portnumber);
    } catch (Exception e) { TextArea.AddLine("Can't disconnect.."); }
}

    synchronized void remove(int id) {
        // scan the array list until we find the Id
        for(int i = 0; i < al.size(); ++i) {
            ClientThread ct = al.get(i);
            // found it
            if(ct.id == id) {
                al.remove(i);
                return;
            }
        }
    }

public static boolean isRunning(){
    return running;
}

    class ClientThread extends Thread {
        //The socket where to listen/talk
        Socket socket;
        ObjectInputStream sInput;
        ObjectOutputStream sOutput;
        //my unique id (easier for deconnection)
        int id;
        //Objects that we will be receiving
        Incomingdata datain;
        //the date we connect
        String date;
        Player player;

        //Constructor
        ClientThread(Socket socket){
            id = uniqueId++;
            this.socket = socket;
            try{
                sOutput = new ObjectOutputStream(socket.getOutputStream());
                sInput = new ObjectInputStream(socket.getInputStream());
            } catch (Exception e){
                System.out.println("Couldn't create Input/Output streams");
            }
            date = new Date().toString();
        }

        // what will run forever
        public void run() {
            // to loop until LOGOUT
            boolean Connected = true;
            while(Connected) {
                // Read incoming data
                try {
                    //Everything works until that
                    datain = (Incomingdata) sInput.readObject();
                    //at this point the program restarts?
                }
                catch (IOException e) {
                    TextArea.AddLine(Incomingdata.getUsername(datain) + " Exception reading Streams: " + e);
                    break;              
                }
                catch(ClassNotFoundException e2) {
                    break;
                }
                if(datain != null){
                    // Switch on the type of message receive
                    switch(Incomingdata.getAction(datain).getType()) {

                    case 0://Log off
                        TextArea.AddLine(Player.getUsername(player) + " logged off.");
                        Connected = false;
                        break;
                    case 1://Talk
                        TextArea.AddLine(Incomingdata.getUsername(datain) + ": " +Incomingdata.getAction(datain).getString());
                        break;
                    case 2://Move
                        Player.move(player);
                    }
                }
            }
            // remove myself from the arrayList containing the list of the
            // connected Clients
            remove(id);
            close();
        }

        // try to close everything
        private void close() {
            // try to close the connection
            try {
                if(sOutput != null) sOutput.close();
            }
            catch(Exception e) {}
            try {
                if(sInput != null) sInput.close();
            }
            catch(Exception e) {};
            try {
                if(socket != null) socket.close();
            }
            catch (Exception e) {}
        }
    }
}

客户:

package com.connection;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Client {

// for I/O
private ObjectInputStream sInput;       // to read from the socket
private static ObjectOutputStream sOutput;      // to write on the socket
private Socket socket;
private Outgoingdata lastdata;
private Outgoingdata currentdata;
static Client client;
public static boolean connected = false;
public static Player player;

String server;
int port;

Client(String server, int port) {
    this.server = server;
    this.port = port;
}

/*
 * When something goes wrong
 * Close the Input/Output streams and disconnect not much to do in the catch clause
 */
private void disconnect() {
    try { 
        if(sInput != null) sInput.close();
    }
    catch(Exception e) {} // not much else I can do
    try {
        if(sOutput != null) sOutput.close();
    }
    catch(Exception e) {} // not much else I can do
    try{
        if(socket != null) socket.close();
    }
    catch(Exception e) {} // not much else I can do
}

public boolean start() {
    // try to connect to the server
    try {
        socket = new Socket(server, port);
    } 
    // if it failed not much I can so
    catch(Exception ec) {
        System.out.println("Error connectiong to server:" + ec);
        return false;
    }

    System.out.println("Connection accepted " + socket.getInetAddress() + ":" + socket.getPort());

    /* Creating both Data Stream */
    try
    {
        sInput  = new ObjectInputStream(socket.getInputStream());
        sOutput = new ObjectOutputStream(socket.getOutputStream());
    }
    catch (IOException eIO) {
        System.out.println("Exception creating new Input/output Streams: " + eIO);
        return false;
    }

    // creates the Thread to listen from the server 
    new ListenFromServer().start();
    // Send our username to the server this is the only message that we
    // will send as a String. All other messages will be ChatMessage objects
    try
    {
        sOutput.writeObject(new Incomingdata("minisurma", "kaikim", null));
    }
    catch (IOException eIO) {
        System.out.println("Exception doing login : " + eIO);
        disconnect();
        return false;
    }
    // success we inform the caller that it worked
    return true;
}

public static void Connect() {
    // default values
    int portNumber = 1500;
    String serverAddress = "localhost";

    // create the Client object
    client = new Client(serverAddress, portNumber);
    // test if we can start the connection to the Server
    // if it failed nothing we can do
    if(!client.start())
        return;
    connected = true;
}

public static void Disconnect() {
    connected = false;
    client.disconnect();
}

class ListenFromServer extends Thread {

    public void run() {
        while(true) {
            try {
                Outgoingdata data = (Outgoingdata) sInput.readObject();
                System.out.println("data");
            }
            catch(IOException e) {
                System.out.println("Server has closed the connection: " + e);
            }
            // can't happen with a String object but need the catch anyhow
            catch(ClassNotFoundException e2) {
            }
        }
    }
}

public static void send(Incomingdata incomingdata) {
    try {
        sOutput.writeObject(incomingdata);
    }
    catch(IOException e) {
        System.out.println("Exception writing to server: " + e);
    }
}
}

共有1个答案

红存
2023-03-14

客户端说:“服务器已关闭连接:java.net.SocketException:socket closed”

这是你的信息,它是不正确的。您假设每个IOException都意味着服务器关闭了连接。当然不是这样。真正意义上的两个例外是eofeexception和通常的IOException:connection reset

这个特殊的异常是一个SocketException:socket closed,它的意思是您,即客户端,关闭了连接,然后继续使用它。例如,如果初始登录失败,则断开连接,但侦听器线程仍在运行,正在尝试读取。

不要做出错误的假设来误导自己,尤其是不要把它们建立在错误信息中。

注意:

>

  • 您需要在ObjectInputStream之前创建ObjectOutputStream

    您的侦听器线程需要捕获EOFException,并在捕获时跳出循环

  •  类似资料:
    • 什么是套接字? Socket是一种Berkeley UNIX机制,用于在不同进程之间创建虚拟双工连接。 随后将其移植到每个已知的OS上,使得能够跨越在不同OS软件上运行的地理位置的系统之间进行通信。 如果不是套接字,系统之间的大多数网络通信永远不会发生。 仔细看看; 网络上的典型计算机系统根据其上运行的各种应用程序接收和发送信息。 此信息被路由到系统,因为为其指定了唯一的IP地址。 在系统上,此信

    • 本文向大家介绍Java套接字(Socket)网络编程入门,包括了Java套接字(Socket)网络编程入门的使用技巧和注意事项,需要的朋友参考一下 网络应用模式主要有: 主机/终端模式:集中计算,集中管理; 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理; 浏览器/服务器模式:利用Internet跨平台。 www(万维网)就是建立在客户机/服务器模式上,以HTML

    • 桌面(或手机)本地应用都可以通过TCP协议和服务器实现全双工通信,也就是建立一个套接字连接(Socket),然后在上面双向传送数据,客户端和服务器都可以发送和接收消息。 但是在传统的网页模型中,通过HTTP协议仅能实现单向的通信,即浏览器发送请求,而服务器被动应答请求,服务器不能主动推送信息给到网页端。 那么很多网站为了实现“实时信息推送”的效果,大都采用了轮询(Polling)或Comet技术,

    • 问题内容: 我正在研究并尝试制作一个简单的应用程序。这是代码: 编辑: 我的错,抱歉,但主要问题仍然存在。这是更正的代码: 但是,当我尝试启动它时,出现以下错误: 这可能是什么原因? UPD: 这是其余的痕迹: 问题答案: 这可能是什么原因? 的原因是您尚未向程序传递任何参数。因此,不会引用有效的数组索引(顺便说一句:我将创建一个单独的局部变量,而不是分配给该数组。从技术上讲,这是可能的,但我不会

    • 本文向大家介绍Python socket 套接字实现通信详解,包括了Python socket 套接字实现通信详解的使用技巧和注意事项,需要的朋友参考一下 首先:我们介绍一下socket什么是socket: 1. socket 在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的接口(接收数据的),此接口接受数据之后交个操作系统 那么为什么?直接给操作系统不是更方便吗?那么你就想

    • 我想更改整个应用程序组件(文本视图、编辑文本、按钮等)的字体。我发现我可以为应用程序设置样式,但在这里我无法将字体从资产文件夹放入自定义样式xml。我必须将我的自定义TTF字体从资产文件夹放到样式xml中的typeface元素中。我无法将单空间字体更改为自定义字体。我的风格是