简体   繁体   English

用Java多线程处理此网络代码?

[英]Multithreading this networking code in Java?

I'm trying to build a chat application on a CS framework, but I haven't quite figured out how to multithread the client code. 我正在尝试在CS框架上构建聊天应用程序,但是我还没有弄清楚如何对客户端代码进行多线程处理。 I'd appreciate it if someone could point me in the right direction. 如果有人能指出我正确的方向,我将不胜感激。

For starters, this bit of code just allows the client and server to communicate bidirectionally: 对于初学者来说,这段代码仅允许客户端和服务器进行双向通信:

I won't paste the entire code, just the most important bits 我不会粘贴整个代码,仅粘贴最重要的部分

Server 服务器

// main
public static void main (String[] args) {
    ChatServer cs = new ChatServer();
    cs.runServer();
}

// run ChatServer
public void runServer() {
    try {
        server = new ServerSocket (12345, 100);

        while (true) {
            try {
                waitForConnection();    // wait for connection
                getStreams();           // get IO streams
                processConnection();    // process connection
            } catch (EOFException eofException) {
                System.out.println("Server terminated connection");
            } finally {
                closeConnection();      // close connection
                ++counter;
            }
        }
    } catch (IOException ioException) {
        ioException.printStackTrace();
    }
}

// wait for connection, and display connection info
private void waitForConnection() throws IOException {
    System.out.println("Waiting for connection");
    connection = server.accept();
    System.out.println("Connection: " + counter + " received from: " + 
                    connection.getInetAddress().getHostName());
}

// get streams to send and receive data
private void getStreams() throws IOException {
    // set up output stream
    output = new ObjectOutputStream(connection.getOutputStream());
    output.flush();                     // flush output buffer to send header information

    // set up input stream
    input = new ObjectInputStream(connection.getInputStream());

    System.out.println("Got I/O streams");
}

private void processConnection() throws IOException {
    String message = "Connection succesful";
    sendData(message);

    do {    // process messages sent from client
        try {
            message = (String) input.readObject();  // read new message
            System.out.println(message);        // display message
        } catch (ClassNotFoundException classNotFoundException) {
            System.out.println("Unkonwn object type received!");
        }
    } while (!message.equals("CLIENT>>> TERMINATE"));
}

Client 客户

public static void main (String[] args) {
    Client application;

    // if no command line args
    if (args.length == 0) {
        application = new Client("127.0.0.1");
    } else {
        application = new Client(args[0]);
    }
}

// connect to server and process messages from server
public void runClient() {
    try {
        connectToServer();      // create Socket to connect to server
        getStreams();           // get input and output streams
        processConnection();    // process connection
    } catch (IOException ioException) {
        ioException.printStackTrace();
    } finally {
        closeConnection();
    }
}

// connect to server
private void connectToServer() throws IOException {
    displayMessage("Attempting connection\n");

    // create Socket to connect to server
    client = new Socket(InetAddress.getByName(chatServer), 12345);

    // dispaly connection information
    displayMessage("Connected to: " + client.getInetAddress().getHostName());
}

// get streams to send and receive data
private void getStreams() throws IOException {
    // set up output stream for objects
    output = new ObjectOutputStream(client.getOutputStream());
    output.flush();

    // set up input stream for objects
    input = new ObjectInputStream(client.getInputStream());

    displayMessage("\nGot I/O streams\n");
}

// process connection with server
private void processConnection() throws IOException {
    // enable enter field to send messages
    setTextFieldEditable(true);

    do {
        try {
            message = (String)input.readObject();
            displayMessage("\n" + message);
        } catch (ClassNotFoundException classNotFoundException) {
            displayMessage("\nUnknown object type received!");
        }
    } while (!message.equals("SERVER>>> TERMINATE"));
}

// close streams and socket
private void closeConnection() {
    displayMessage("\nClosing connection");
    setTextFieldEditable(false);

    try {
        output.close();
        input.close();
        client.close();
    } catch (IOException ioException) {
        ioException.printStackTrace();
    }
}

My initial thoughts: 我最初的想法:

  1. The Client class should implement runnable, but I'm not sure what the run() method should wrap around... Client类应该实现runnable,但是我不确定run()方法应该包含哪些内容...

  2. The Server class - I have a feeling the key is in the accept() line, but I'm not sure how to proceed... Server类-我觉得关键是在accept()行中,但是我不确定如何继续...

I've only started learning multithreading in Java, but we're expected to build this multithreaded networking chat app lately, so I'm kinda lost as to how to proceed. 我只是开始学习Java中的多线程,但是最近我们期望构建此多线程网络聊天应用程序,因此我对如何进行操作有点迷茫。

Would appreciate any guidance on this, thanks! 希望对此有任何指导,谢谢!

To keep this answer short, you need to basically, 为使答案简短,您基本上需要

  1. extract the methods getStreams() and processConnecion() inside a class that implements Runnable . 在实现Runnable的类中提取方法getStreams()processConnecion() These methods will be running in a Thread 这些方法将在线程中运行
  2. After waitForConnection() , construct your new Runnable Class, inject it your connection (or Streams) and start() it waitForConnection() ,构造您的新Runnable类,将其注入您的connection (或Streams)中,并对其进行start()

Multithreading is very tough, and Java is absolutely no exception. 多线程非常困难,Java绝对也不例外。 Before you go too far in your application, make sure you fully understand how the Java Memory Model works and follow simple rules: 在深入您的应用程序之前,请确保您完全了解Java内存模型的工作原理并遵循简单的规则:

  • make variables as immutable as you can 使变量尽可能不变
  • avoid global or instance variable wherever you can 尽可能避免全局变量或实例变量
  • do not re-invent the wheel, use (abuse) the classes in the java.util.concurrent package 不要重新发明轮子,使用(滥用) java.util.concurrent包中的类
  • do not use synchronized all over the place 'just in case': your app will be inefficient and may just work better on a single thread 不要在所有情况下都使用synchronized ,以防万一:您的应用程序效率低下,可能在单个线程上工作得更好

A an alternative to the Multithreading model, look at Actors using the Akka library 作为多线程模型的替代方法,请使用Akka库查看Actors

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

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