构建多端口服务器:Java
我正在尝试构建一个带有线程的多端口服务器。我还有一个 ClientManager 类和一个 Client 类。需要发生的是用户输入一系列端口...例如端口 8000-8010。服务器需要侦听所有这些端口的连接。然后,ClientManager 获取端口范围并为每个端口创建一个客户端实例。然后,客户端以 0-1 秒之间的随机间隔向服务器发送消息。客户端发送 100 条消息后,它应该断开连接。服务器需要每 5 秒打印出它收到了多少条消息。
到目前为止,我已经设法获取端口范围的用户输入,然后通过 Runtime.exec() 参数将它们发送到 ClientManager。这是我当前的服务器和客户端管理器代码:
import java.io.*;
public class Server{
public static void main(String[] args){
try{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader userInputReader = new BufferedReader(isr);
String lowPortRange = null;
String highPortRange = null;
System.out.println("Enter low end of port range:");
if((lowPortRange = userInputReader.readLine())!=null){
System.out.println("Low Range: " + lowPortRange);
}
System.out.println("Enter high end of port range:");
if((highPortRange = userInputReader.readLine()) != null){
System.out.println("High Range: " + highPortRange);
}
int lowPort = Integer.parseInt(lowPortRange);
int highPort = Integer.parseInt(highPortRange);
int totalPorts = highPort - lowPort+1;
System.out.println("Total ports: " + totalPorts);
System.out.println("...Port numbers...");
for(int port = lowPort; port<=highPort; port++){
System.out.println(port);
}
System.out.println("Done!");
System.out.println();
Process p = Runtime.getRuntime().exec("java ClientManager " + lowPort + " " + highPort);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}catch(IOException e){
System.out.println("IOException!");
e.printStackTrace();
}
}
}
import java.io.*;
public class ClientManager{
private int lowPort;
private int numPorts;
public static void main(String[] args){
System.out.println("ClientManager Started.");
int firstPort = Integer.parseInt(args[0]);
int lastPort = Integer.parseInt(args[1]);
System.out.println("First Port: " + firstPort);
System.out.println("Last Port: " + lastPort);
}
}
我的问题基本上是这样的:有人可以从理论上解释一下我应该从这里去哪里吗?
I'm trying to build a Multi-port server with threads. I also have a ClientManager class and a Client class. What needs to happen is the user enters a range of ports...say ports 8000-8010. The Server needs to listen at all of those ports for connections. The ClientManager then gets the range of ports and creates a Client instance for each one. The Client then sends messages to the Server in random intervals between 0-1 seconds. After 100 messages are sent by a client, it should disconnect. The server needs to print out how many messages it has received every 5 seconds.
So far I've managed to get the user inputs for the range of ports and then send them over to the ClientManager via Runtime.exec() parameters. Here's my current code for the Server and ClientManager:
import java.io.*;
public class Server{
public static void main(String[] args){
try{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader userInputReader = new BufferedReader(isr);
String lowPortRange = null;
String highPortRange = null;
System.out.println("Enter low end of port range:");
if((lowPortRange = userInputReader.readLine())!=null){
System.out.println("Low Range: " + lowPortRange);
}
System.out.println("Enter high end of port range:");
if((highPortRange = userInputReader.readLine()) != null){
System.out.println("High Range: " + highPortRange);
}
int lowPort = Integer.parseInt(lowPortRange);
int highPort = Integer.parseInt(highPortRange);
int totalPorts = highPort - lowPort+1;
System.out.println("Total ports: " + totalPorts);
System.out.println("...Port numbers...");
for(int port = lowPort; port<=highPort; port++){
System.out.println(port);
}
System.out.println("Done!");
System.out.println();
Process p = Runtime.getRuntime().exec("java ClientManager " + lowPort + " " + highPort);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}catch(IOException e){
System.out.println("IOException!");
e.printStackTrace();
}
}
}
import java.io.*;
public class ClientManager{
private int lowPort;
private int numPorts;
public static void main(String[] args){
System.out.println("ClientManager Started.");
int firstPort = Integer.parseInt(args[0]);
int lastPort = Integer.parseInt(args[1]);
System.out.println("First Port: " + firstPort);
System.out.println("Last Port: " + lastPort);
}
}
My question is basically this: Could someone explain, theoretically, where I should go from here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要为您正在侦听的每个端口创建一个 ServerSocket。因为accept() 会阻塞直到客户端连接,所以您需要创建一个线程来侦听每个ServerSocket。如果多个客户端可能同时连接到给定端口(从您的描述看来并非如此),您还必须为每个客户端连接创建一个线程。还有一个每 5 秒打印一次消息计数并将其归零——这也可能是主线程。
当然,对消息计数的访问必须正确同步,并且描述没有提到如果必须优雅地完成服务器应该何时关闭。
(旁注:在客户端连接时不接受新连接在“真实”服务器中显然是不可接受的,如果有很多客户端,每个客户端一个线程并不是避免这种情况的最佳方法。)
You need to create one ServerSocket for every port you're listening on. Because accept() blocks until a client connects, you'll need to create one thread to listen on each ServerSocket. If more than one client may be connected to a given port at the same time (doesn't seem that way from your description), you'll also have to create one thread for every client connection. And one more to print and zero the message count every 5 seconds – this might as well be the main thread.
Of course, access to the message count will have to be properly synchronised, and the description doesn't mention when the server should shut down if it has to be done gracefully at all.
(Sidenote: not accepting new connections while a client is connected is obviously unacceptable in a "real" server, and one-thread-per-client is not the optimal way to avoid this if you have many clients.)
有关更多信息,请参阅 ThreadPoolExecutor。它将使您的服务器变得健壮。您可以根据您的需求构建它。如果您从未使用过 Executors,那根本不是问题。很简单。您只需为其提供需要处理的 Runnable ,在这种情况下,一旦获得连接,然后与客户端交互等。您的大部分负载都会减少。
See ThreadPoolExecutor for more Info. It will make your sever robust. And you can structure it to suit your demands. If you have never worked it with Executors, not at all an issue. very simple. You will have to just give it Runnable which you need to process, in this case once you get the connection, then the interaction with client etc. Most of your load will get reduced.