我正在制作一个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.
}
感谢。
答案 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>
(它可以是您自己的单例,在读取传入数据时可供所有线程访问),然后通过请求参数(用户)检索所需的会话。