我有一个将客户端连接到服务器的java程序。 这包括在客户端通过发送消息触发服务器后创建文件目录。例如:一旦服务器已经运行,客户端将连接并将发送一个消息,即“你的消息:Lady”,服务器将收到一条消息,如“请求创建名为:Lady的目录”,此后是一个目录将被命名为Lady。
但问题是这种联系只适用于一对一。就像只有一个客户端可以连接到服务器......
这是示例代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package today._;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
public class myServer {
protected static final int PORT_NUMBER = 55555;
public static void main(String args[]) {
try {
ServerSocket servsock = new ServerSocket(PORT_NUMBER);
System.out.println("Server running...");
while (true) {
Socket sock = servsock.accept();
System.out.println("Connection from: " + sock.getInetAddress());
Scanner in = new Scanner(sock.getInputStream());
PrintWriter out = new PrintWriter(sock.getOutputStream());
String request = "";
while (in.hasNext()) {
request = in.next();
System.out.println("Request to Create Directory named: " + request);
if(request.toUpperCase().equals("TIME")) {
try {
File file = new File("C:\\" + request);
if (!file.exists()) {
if (file.mkdir()) {
System.out.println("Directory is created!");
} else {
System.out.println("Failed to create directory!");
}
}
} catch (Exception e) {
System.out.println(e);
}
out.println(getTime());
out.flush();
} else {
out.println("Invalid Request...");
out.flush();
}
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
protected static String getTime() {
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
return (dateFormat.format(date));
}
}
package today._;
import java.io.*;
import java.net.*;
import java.util.*;
public class myClient {
protected static final String HOST = "localhost";
protected static final int PORT = 55555;
protected static Socket sock;
public static void main(String args[]) {
try {
sock = new Socket(HOST,PORT);
System.out.println("Connected to " + HOST + " on port " + PORT);
Scanner response = new Scanner(sock.getInputStream());
PrintWriter request = new PrintWriter(sock.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String txt = "";
while(!txt.toUpperCase().equals("EXIT")) {
System.out.print("Your message:");
txt = in.readLine();
request.println(txt);
request.flush();
System.out.println(response.next());
}
request.close();
response.close();
in.close();
sock.close();
} catch(IOException e) {
System.out.println(e.toString());
}
}
}
答案 0 :(得分:2)
多客户端服务器通常采用以下两种方式之一:
为每个客户创建一个主题。为此,您将创建一个线程来处理对服务器套接字上的accept()的调用,然后生成一个新线程来处理它返回的Socket上的调用。如果这样做,您需要确保尽可能地隔离每个套接字的代码。接受线程将永远循环,或者直到设置一个标志,并且只调用accept,用新套接字生成一个线程,然后返回调用accept。所有的工作都在子线程中。
使用NIO或其他技术将多重工作分成1个以上的线程。 NIO使用有时称为select的概念,当特定套接字有输入时,将调用您的代码。
如果你只是做一个小型服务器,你可以选择最简单的设计,也不会有太多的客户端,所以我会选择#1。如果你正在做一个大型的生产服务器,我会调查一个像netty或jetty这样的框架来帮助你做#2。 NIO可能很棘手。
在任何一种情况下,都要非常小心线程和文件系统,如果你不使用并发包中的Lock,或者同步或其他锁定方案,你可能得不到预期的结果。
我的最后建议,小心让客户告诉服务器对文件系统做任何事情。只是说,这是一件危险的事情; - )
答案 1 :(得分:1)
您的服务器类必须使用多个线程来处理所有连接:
class MyServer {
private ServerSocket servsock;
MyServer(){
servsock = new ServerSocket(PORT_NUMBER);
}
public void waitForConnection(){
while(true){
Socket socket = servsock.accept();
doService(socket);
}
}
private void doService(Socket socket){
Thread t = new Thread(new Runnable(){
public void run(){
while(!socket.isClosed()){
Scanner in = new Scanner(sock.getInputStream());
PrintWriter out = new PrintWriter(sock.getOutputStream());
String request = "";
// and write your code
}
}
});
t.start();
}
}