将变量设置为客户端套接字

时间:2013-12-02 17:47:24

标签: java sockets

我正在制作一个Java TCP服务器和一个我无法解决的noob问题来找我,将变量设置到当前客户端套接字的方法是什么?检查类Handler,上面的代码可能并不重要。

import java.io.*;
import java.net.*;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Handler;

public class tcp_server {
  public static void main(String[] args) {
    int count = 0;

    ExecutorService executor = Executors.newFixedThreadPool(30);
    Socket client;

    try {
      ServerSocket server = new ServerSocket(8080);

      while(true) {
        client = server.accept();
        executor.execute(new Handler(client));
      }
    }
    catch(Exception e) {
      System.out.println(e);
    }
  }

  public static class Handler implements Runnable {
    private Socket client;

    public Handler(Socket client) {
      this.client = client;
    }

    public void run() {
      try {
        BufferedReader inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
        DataOutputStream outToClient = new DataOutputStream(client.getOutputStream());
        String event = inFromClient.readLine();
        System.out.println(event);

        // Arrays.copyOfRange(byte[] original, int from, int to)

        // Index
        if(event.equals("GET / HTTP/1.1")) {
          // ...
          client.close();
        }

        // Authenticate
        if(event.charAt(0) == '0') {
          String client_token = Arrays.copyOfRange(byte[] event, int 1, 33);

          // I'm gonna add the MySQL Queries later

          // if session id found on table
          String client_google = "000000000000000000000"; // MySQL
          client.session = client_token; // -> Token received from client. (?)
          client.gid = client_google; // -> Google+ Profile (?)
          // **How do I set variables to the current client?**
        }

        // Sync settings
        if(event.charAt(0) == '0') {
          // ...
          // access non static variable from here
          System.out.println(client.session); // (?)
          System.out.println(client.gid); // (?)
        }

        // More events
      }
      catch(Exception e) {
        System.out.println(e);
      }
    }
  }

  // End.
}

感谢。

1 个答案:

答案 0 :(得分:1)

有几种方法可以将数据存储在特定连接的本地。 在您的示例中,最简单的方法是声明一个session-variable,它是Handler的一个字段,如:

public static class Handler implements Runnable {
    private Socket client;  
    private UserSession session;

    public Handler(Socket client) {
      this.client = client;
      this.session = new UserSession();
    }
 ...

UserSession可以包含您想要的内容。另一种选择是将UserSession类交换为Map<String, Object>,它将保存此用户连接本地的键值映射。缺点:如果系统增长,则必须将对此会话的引用传递给需要会话数据的所有方法。

只要您使用阻塞IO进行数据输入,您也可以使用ThreadLocal这样的类,它与java一起开箱即用。此机制与本地变量UserSession的作用相同,只要代码由1个线程运行(阻塞IO的事实),您的会话变量就可以在代码的任何部分中访问。你可以在这里阅读:

http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html

最后一种方式 - 非阻塞线程池HTTP方式 - 为每个请求发送会话标识符,例如user=login。接下来,在应用程序上下文中存储一个大Map<String, UserSession>(它可以是您自己的单例,在读取传入数据时可供所有线程访问),然后通过请求参数(用户)检索所需的会话。