客户端 - 服务器连接

时间:2013-07-14 08:14:08

标签: java

我有一个将客户端连接到服务器的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());
           }
      }

 }

2 个答案:

答案 0 :(得分:2)

多客户端服务器通常采用以下两种方式之一:

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

  2. 使用NIO或其他技术将多重工作分成1个以上的线程。 NIO使用有时称为select的概念,当特定套接字有输入时,将调用您的代码。

  3. 如果你只是做一个小型服务器,你可以选择最简单的设计,也不会有太多的客户端,所以我会选择#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();
    }
}