2

我有一个将客户端连接到服务器的java程序。这包括在客户端通过发送消息触发服务器后创建文件目录。例如:一旦服务器已经运行,客户端将连接并发送一条消息,即“您的消息:女士”,服务器将收到一条消息,如“请求创建名为:女士的目录”,之后是一个目录将创建名为 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());
           }
      }

 }
4

2 回答 2

2

多客户端服务器一般采用以下两种方式之一编写:

  1. 为每个客户端创建一个线程。为此,您将创建一个线程来处理对服务器套接字上的 accept() 的调用,然后生成一个新线程来处理它返回的 Socket 上的调用。如果这样做,则需要确保尽可能地隔离每个套接字的代码。接受线程将永远循环,或者直到设置一个标志,并且只会调用接受,使用新套接字生成一个线程,然后返回调用接受。所有的工作都在子线程中。

  2. 使用 NIO 或其他技术将工作多路复用到 1 个以上的线程中。NIO 使用一个有时称为 select 的概念,当有来自特定套接字的可用输入时,您的代码将被调用。

如果你只是做一个小服务器,你可以用最简单的设计,也不会有太多的客户端,所以我会选择#1。如果你正在做一个大型生产服务器,我会研究一个像 netty 或 jetty 这样的框架来帮助你做#2。NIO 可能很棘手。

无论哪种情况,都要非常小心线程和文件系统,如果您不使用并发包中的锁、同步或其他锁定方案,您可能无法获得预期的结果。

我最后的建议是,让客户端告诉服务器对文件系统做任何事情时要小心。只是说,这是一件危险的事情;-)

于 2013-07-14T08:25:22.567 回答
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();
    }
}
于 2013-07-14T08:29:46.720 回答