2011-02-24 46 views
27

我试图去适应我的简单的socket服务器,以便它可以有多个TCP连接的多个连接,通过多线程,但我似乎无法得到它的工作。到目前为止我的代码如下所示,我真的不知道从哪里何去何从:创建一个套接字服务器允许通过线程和Java

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等等等等

会有人能够帮我这个?

非常感谢!

回答

50

的问题是,目前你正在接受连接,但直到它的关闭就可以了,然后立即进行拦截写着:

// 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 ...。)

+0

你能不能举一个例子你建议那个班? – 2016-07-19 13:27:05

+0

@DanyLavrov:不,我想我已经在这里提供了足够的信息 - 我并不想开始做大量的工作来添加一个超过5年的答案,并且它看起来对大多数人来说有足够的信息。如果您尝试使用它并遇到问题,也许您应该提出一个新问题,显示您尝试过的以及出错的地方,并参考此答案。 – 2016-07-19 13:29:12

+0

并不重要。我已经知道了,谢谢。 – 2016-07-19 15:42:08

17

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

您需要的插座传递到一个新的线程,并把它读。

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(); 
} //... 
相关问题