【问题标题】:Creating a socket server which allows multiple connections via threads and Java创建一个允许通过线程和 Java 进行多个连接的套接字服务器
【发布时间】:2011-02-24 19:47:02
【问题描述】:

我正在尝试调整我的简单套接字服务器,以便它可以通过多线程进行多个 TCP 连接,但我似乎无法让它工作。到目前为止,我的代码如下,我不确定从这里去哪里:

import java.net.*;
import java.io.*;

public class DoSomethingWithInput implements Runnable {
   private final Socket clientSocket; //initialize in const'r
   public void run() {


     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String nextline;
        while ((nextline = in.readLine())!=null) {
           System.out.println(nextline);
        } //... close socket, etc.
    }
}


public class Socket{

  public Socket() {
}
@Override
public void run() {
  try {
    ServerSocket serverSocket = null;
    serverSocket = new ServerSocket(5432);
    for (;;) {
      ServerSocket serverSocket = null;
      serverSocket = new ServerSocket(5432);
      for (;;) {
        Socket clientSocket = null;
        clientSocket = serverSocket.accept();
        //delegate to new thread
        new Thread(new DoSomethingWithInput(clientSocket)).start();
      }
    }
  }catch (IOException e) {
   System.err.println("Could not listen on port: 5432.");
   System.exit(1);
}
}
}

谁能给我一些关于如何做到这一点的指示,以及为什么我当前的实现不起作用?我在这里查看了 Java 教程 http://download.oracle.com/javase/tutorial/networking/sockets/examples/KKMultiServerThread.java 中的提示,但他们在此处给出的示例似乎使用了许多外部资源和类,如 KnockKnockProtocol 等。

有人能帮我解决这个问题吗?

非常感谢!

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    问题是当前您正在接受连接,但随后立即对其执行阻塞读取直到它关闭:

    // After a few changes...
    Socket clientSocket = serverSocket.accept();
    BufferedReader in = new BufferedReader(new InputStreamReader(
         clientSocket.getInputStream()));
    String nextLine;
    while ((nextLine = in.readLine()) != null) {
        System.out.println(nextline);
    }
    

    这意味着接受连接的同一线程正在尝试处理连接。这不会让您同时使用多个连接。

    相反,创建一个实现Runnable 的类(例如ConnectionHandler),并有一个采用Socket 的构造函数。它的run 方法应该处理连接。然后将代码更改为:

    Socket clientSocket = serverSocket.accept();
    Runnable connectionHandler = new ConnectionHandler(clientSocket);
    new Thread(connectionHandler).start();
    

    这将使您的“主”线程空闲等待下一个连接。

    (顺便说一句,KnockKnockProtocol 类并不是真正的“外部”类——它是示例的一部分。他们只是没有明确说明 source is here...)

    【讨论】:

    • 你能举一个你建议的课程的例子吗?
    • @DanyLavrov:不,我想我已经在这里提供了足够的信息 - 我真的不想开始做大量工作来添加超过 5 年的答案,看起来像它为大多数人提供了足够的信息。如果您尝试使用它并遇到问题,也许您应该提出一个新问题,说明您尝试过什么以及出了什么问题,并参考此答案。
    • 没关系。我已经弄明白了,谢谢。
    【解决方案2】:

    你不是多线程。您正在创建一个绑定端口的线程,然后从任何客户端套接字读取,直到连接关闭。

    您需要将套接字传递给一个新线程并读取它。

    public class DoSomethingWithInput implements Runnable {
       private final Socket clientSocket; //initialize in const'r
       public void run() {
    
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            String nextline;
            while ((nextline = in.readLine())!=null) {
               System.out.println(nextline);
            } //... close socket, etc.
        }
    }
    
    //...
    ServerSocket serverSocket = null;
    serverSocket = new ServerSocket(5432);
    for (;;) {
        Socket clientSocket = null;
        clientSocket = serverSocket.accept();
        //delegate to new thread
        new Thread(new DoSomethingWithInput(clientSocket)).start();
    } //...
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 2016-03-10
    • 1970-01-01
    相关资源
    最近更新 更多