繁体   English   中英

Java 多线程服务器/客户端逻辑不工作

[英]Java Multi Threaded Server/Client Logic not working

我正在尝试创建一个多线程服务器和客户端对。 这两个类都继承了从公共类中写入和读取的方法。我无法正常工作,并且收到空指针异常。 这是我的代码:

//服务端和客户端的公共类

    package server;

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

public class DefaultSocketClient extends Thread {
    protected ObjectInputStream ois;
    private ObjectOutputStream oos;
    private Socket sok;

    public DefaultSocketClient(Socket sok) {
        this.sok = sok;
    }
public void run() {
    openConnection();
    handleSession();
    // closeSession();
}

/*
 * this methods opens connection
 */

public void openConnection() {
    try {
        ois = new ObjectInputStream(sok.getInputStream());
        oos = new ObjectOutputStream(sok.getOutputStream());
    } catch (IOException e) {
        try {
            throw new AutoException("OpenConnectionException");
        } catch (AutoException e1) {
            e1.printStackTrace();
        }
    }
}

public void handleSession() {
    Object input;
    try {
        while ((input = ois.readObject()) != null) {
            handleInput(input);
        }
    } catch (Exception e) {
        try {
            throw new AutoException("HandleSessionException");
        } catch (AutoException e1) {
            e1.printStackTrace();
        }
    }

}

private void handleInput(Object newInput) {
    System.out.println(newInput);

}

public void sendOutput(Object newOutput) {
    try {
        oos.writeObject(newOutput);
    } catch (IOException ioe) {
        try {
            throw new AutoException("ObjectOutputException");
        } catch (AutoException e1) {
            e1.printStackTrace();
        }
    }
}

/**
 * This method closes the Session between client and server
 */
public void closeSession() {
    try {
        ois.close();
        ois.close();
        sok.close();
    } catch (IOException e) {
        try {
            throw new AutoException("SessionCloseException");
        } catch (AutoException e1) {
            e1.printStackTrace();
        }
    }

}

}

//客户

    /*
     * creating client
     */
    public AutoClientSocket() {
        try {
            clientSocket = new Socket(InetAddress.getLocalHost(),
                    DEFAULT_PORT_NO);
            readFromConsole = new BufferedReader(new InputStreamReader(
                    System.in));
        } catch (Exception e) {
            try {
                throw new AutoException("AutoServerConnectionException");
            } catch (AutoException e1) {
                e1.printStackTrace();
            }

        }
    }

    // starting the client
    public void startAutoClient() {
        try {
            defaultSocketClient = new DefaultSocketClient(clientSocket);
            defaultSocketClient.start();
            System.out.println("Client started...");
            defaultSocketClient.closeSession();

//          performOperation();
        } catch (Exception e) {
            try {
                throw new AutoException("ConnectionException");
            } catch (AutoException e1) {
                e1.printStackTrace();
            }
        }

    }


    public void performOperation() {
        // methods for client operations.

    }

}

//服务器

public class AutoServerSocket {

private int DEFAULT_PORT_NO = 7900;
private static ServerSocket autoServer;
ObjectOutputStream oos;
ObjectInputStream ois;

private DefaultSocketClient defaultSocketClient;
BuildAuto build = new BuildAuto();
FileIO io = new FileIO();

// creating server
public AutoServerSocket() {
    try {
        autoServer = new ServerSocket(DEFAULT_PORT_NO);

        System.out.println("Server started...");
    } catch (Exception e) {
        try {
            throw new AutoException("AutoServerConnectionException");
        } catch (AutoException e1) {
            e1.printStackTrace();
        }

    }
}

// starting the server
public void startAutoServer() {
    Socket sok;
    while (true) {
        try {
            sok = autoServer.accept();
            defaultSocketClient = new DefaultSocketClient(sok);
            defaultSocketClient.start();
            System.out.println("Connection Established....");
            defaultSocketClient.sendOutput(generateAutoWelcome());
            defaultSocketClient.handleSession();
            defaultSocketClient.closeSession();
        } catch (IOException e) {
            try {
                throw new AutoException("ConnectionException");
            } catch (AutoException e1) {
                e1.printStackTrace();
            }
        }
    }
}

/**
 * This method generates Welcome message for AutoWorld
 */
private String generateAutoWelcome() {
    return "--------Welcome to AutoWorld-----------";
}

}

我在服务器上收到以下异常-->

   Exception in thread "main" java.lang.NullPointerException
    at server.DefaultSocketClient.sendOutput(DefaultSocketClient.java:64)
    at server.AutoServerSocket.startAutoServer(AutoServerSocket.java:51)
    at driver.ServerDriver.main(ServerDriver.java:11)

在线:

  oos.writeObject(newOutput);

我显然在这里做错了什么,因为我无法接收我在客户端发送的对象。 有人可以帮帮我吗?

谢谢

你的问题来自那里:

   defaultSocketClient = new DefaultSocketClient(sok);
   start();
   System.out.println("Connection Established....");
   sendOutput(generateAutoWelcome() + generateMainMenu());

您正在创建一个 defaultSocketClient 来处理客户端创建的套接字,但您没有对它做任何事情。

将这些行替换为

   defaultSocketClient = new DefaultSocketClient(sok);
   defaultSocketClient.start();
   System.out.println("Connection Established....");
   defaultSocketClient.sendOutput(generateAutoWelcome() + generateMainMenu());

这应该可以解决您的 NullPointerException 错误。

这里仍然存在一些架构问题。 你的服务器套接字应该有一个线程,它在sok = autoServer.accept();上循环sok = autoServer.accept(); 但您不必使用您的服务器扩展 DefaultSocketClient。 您的服务器将基本上等待新连接并创建 DefaultSocketClient 的新实例。 如果您想稍后重用它们,您的服务器还应该存储 DefaultSocketClient 实例。 否则你应该在你的 sendOutput() 调用之后调用closeSession()

这段代码似乎是为了学习目的,所以使用基本的 java 套接字很好,但如果你不想制作一个真正的/多客户端/可调用的客户端服务器应用程序,我建议你使用一个库。

Java 网络库:

  • Netty确实强大的库,但很难配置,而且非常低级。
  • Kryonet易于使用,具有一些很酷的功能,如对象序列化或主机发现。 可以帮助您在几行中创建客户端和服务器的高级库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM