套接字认证服务器?

6

我目前正在使用Java创建一个桌面应用的认证服务器,并已经成功实现了客户端和服务器之间类似于聊天服务器/客户端的通信。

我知道我只完成了一小部分工作,还有很多事情要学习,但现在我想知道如何进行身份验证。

例如,这是服务器端的代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class LoginServer
{
    public static void main(String[] args) throws Exception {
        int port = 7000;
        int id = 1;

        ServerSocket loginserver = null;
        try
        {
            loginserver = new ServerSocket(port);
            System.out.println("LoginServer started...");
        }
        catch (IOException e) {
            System.out.println("Could not listen on port: " + port);
            System.exit(-1);
        }

        while (true)
        {
            Socket clientSocket = loginserver.accept();
            ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
            cliThread.start();
        }
    }
}

class ClientServiceThread extends Thread
{
    Socket clientSocket;
    int clientID = -1;
    boolean running = true;

    ClientServiceThread(Socket s, int i)
    {
        clientSocket = s;
        clientID = i;
    }

    public void run()
    {
        System.out.println("Accepted Client : ID - " + clientID + " : Address - " + clientSocket.getInetAddress().getHostName());
        try
        {
            BufferedReader   in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter   out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            while (running)
            {
                String clientCommand = in.readLine();
                System.out.println("Client Says :" + clientCommand);
                if (clientCommand.equalsIgnoreCase("quit"))
                {
                    running = false;
                    System.out.print("Stopping client thread for client : " + clientID);
                }
                else
                {
                    out.println(clientCommand);
                    out.flush();
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

如您所见,我读取客户端发送的内容并将其输出到控制台,同时检查客户端是否发送了退出命令。

  • 我想知道如何做到只有在用户和密码被发送后,客户端才能连接到它?

  • 或者,我应该始终接收初始连接,并从那里接收验证信息,如果客户端在3秒内没有发送,则断开连接?

  • 接收新连接并对用户进行身份验证的正确方法是什么?

1个回答

12
你的想法是正确的,但你需要更多地将其视为状态机。
客户端连接后,需要进入登录状态,在那里你期望它发送身份验证信息。如果不正确或超时,则断开连接。
如果正确,则进入命令处理状态。如果收到退出命令,则移动到清理状态或直接断开连接。
这是一个大致的概述:
String line;
while ((line = in.readLine()) != null) {
    switch (state) {
        case login:
            processLogin(line);
            break;
        case command:
            processCommand(line);
            break;
    }
}

你的 processLogin 函数可以像这样:

void processLogin(String line) {
    if (user == null) {
        user = line;
    }
    else if (password == null) {
        password = line;
    }
    else {
        if (validUser(user, password)) {
            state = command;
        }
        else {
            socket.close();
        }
    }
}

而你的processCommand函数:

void processCommand(String line) {
    if (line.equals(...)) {
        // Process each command like this
    }
    else if (line.equals("quit")) {
        socket.close();
    }
    else {
        System.err.println("Unrecognized command: " + line);
    }
}

state 实例变量很可能是一个枚举类型。你可以看到使用这个模型会给你一些非常简单的可扩展性。例如,一个命令可以将你置于不同的状态来处理特定的子命令。


感谢您的回答,我很高兴自己没有太离谱。我也试图寻找任何直接针对身份验证套接字系统的源或示例,但是没有找到可以帮助我的。您能否给我提供一个简短的代码示例,或者指导我查看任何可能有助于我的登录系统状态机或类似内容的链接?再次感谢您。 - Guapo
非常感谢您抽出时间帮我,这对我非常有帮助 ;) - Guapo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接