简体   繁体   English

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

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

I am trying to create a Multithreaded server and client pair.我正在尝试创建一个多线程服务器和客户端对。 Both of these classes are inheriting methods for writing and reading from a common class..I am not able to work these properly and am receiving a Null Pointer Exception.这两个类都继承了从公共类中写入和读取的方法。我无法正常工作,并且收到空指针异常。 Here's my code:这是我的代码:

//Common class for server and client //服务端和客户端的公共类

    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();
        }
    }

}

} }

//client //客户

    /*
     * 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.

    }

}

//server //服务器

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-----------";
}

} }

I am getting the following exception at the server-->我在服务器上收到以下异常-->

   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)

at Line:在线:

  oos.writeObject(newOutput);

I am clearly doing something wrong here as I am not able to receive the object I send at the client side.我显然在这里做错了什么,因为我无法接收我在客户端发送的对象。 Can someone please help me?有人可以帮帮我吗?

Thanks谢谢

Your problem comes from there:你的问题来自那里:

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

You are creating a defaultSocketClient to handle the socket created by the client but you don't do anything with it.您正在创建一个 defaultSocketClient 来处理客户端创建的套接字,但您没有对它做任何事情。

Replace these lines by将这些行替换为

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

This should solve your NullPointerException bug.这应该可以解决您的 NullPointerException 错误。

You still have some architecture issues here.这里仍然存在一些架构问题。 You should have a thread for your server socket which loop on sok = autoServer.accept();你的服务器套接字应该有一个线程,它在sok = autoServer.accept();上循环sok = autoServer.accept(); but you don't have to extend DefaultSocketClient with your server.但您不必使用您的服务器扩展 DefaultSocketClient。 Your server will basicaly wait for new connection and create new instances of DefaultSocketClient.您的服务器将基本上等待新连接并创建 DefaultSocketClient 的新实例。 Your server should also store DefaultSocketClient instance if you want to reuse them later.如果您想稍后重用它们,您的服务器还应该存储 DefaultSocketClient 实例。 Otherwise you should just call closeSession() after your sendOutput() call.否则你应该在你的 sendOutput() 调用之后调用closeSession()

This code seems to be for learning purpose so it's fine using basic java sockets but if you wan't to make a real/multiclient/scallable client server app i recommand you use a lib for that.这段代码似乎是为了学习目的,所以使用基本的 java 套接字很好,但如果你不想制作一个真正的/多客户端/可调用的客户端服务器应用程序,我建议你使用一个库。

Java networking libs : Java 网络库:

  • Netty Realy powerfull lib but can be hard to configure proberly and is really low level. Netty确实强大的库,但很难配置,而且非常低级。
  • Kryonet Easy to use with some cool features like object serialisation or host discovery. Kryonet易于使用,具有一些很酷的功能,如对象序列化或主机发现。 Hight level lib that can help you create client and server in few lines.可以帮助您在几行中创建客户端和服务器的高级库。

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

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