我正在编写一个简单的文件服务器,让用户telnet,提供用户名并搜索给予该用户的访问级别,然后显示文件列表,只允许他们查看文件的内容文件,如果他们有足够的访问级别。这段代码是针对服务器端的,我只是为客户端使用PuTTY
我读了用户文件(用冒号分隔以分隔名称和访问级别)
paul:10
schemm:8
bobbarker:0
使用此代码
static Map<String, Integer> users = new HashMap<String, Integer>();
file = new File("userfile.txt");
try
{
out.println("Reading userfile.txt");
Scanner scannerusers = new Scanner(file);
while (scannerusers.hasNextLine())
{
String line = scannerusers.nextLine();
line.trim();
String field[] = line.split(":");
users.put(field[0], Integer.parseInt(field[1]));
}
scannerusers.close();
}
catch (FileNotFoundException e)
{
out.println("userfile.txt not found!");
}
但我的实际问题在这里(至少我认为)。未注释和注释的代码在第一次尝试时都会失败,但在第二次尝试时会失败。
//socket connection stuff here, and all this is nested in a try-catch to get
//connection errors
while(!check)
{
outToClient.writeBytes("What is your username?");
clientinput = inFromClient.readLine();
String username = clientinput;
//
if(users.get(username) == null)
{
outToClient.writeBytes("Invalid username");
}
else
{
check = true;
}
//
//try
//{
// accesslevel = users.get(username);
// check = true; //my thinking was that the NullPointerException would be thrown
// //before this point, but either way doesn't fix the problem
//}
//catch(NullPointerException e)
//{
// outToClient.writeBytes("Incorrect username");
//}
}
编辑:我将完整的源代码放在了pastebin here
上答案 0 :(得分:0)
如果第一次总是失败,并且总是在第二次失败,那么这听起来像是竞争条件。也许文件读取代码由第一个读取操作触发,但是在单独的线程中完成,因此调用线程继续而不是同步等待结果。我们需要确定调用代码。
答案 1 :(得分:0)
或许inFromClient.readLine()
读取的次数(或更少)比您第一次看到的要多。你确定它会回归你的期望吗?我有一段时间没有使用过PuTTY,也许它是在初次连接时发送一些终端控制字符,这些字符是在你第一次读取时被拾取的?您也没有向我们展示连接代码,您是否在此点之前来回发送未完全处理的数据?
答案 2 :(得分:0)
我同意,这听起来像是竞争条件,但我不知道你的代码中会出现竞争条件。也许这就是你打开溪流的方式?现在我有一段时间没玩过Java,但是如果我没记错,我总是有基本流,然后从基本流中打开一个输入流阅读器(我认为),然后用一个缓冲的阅读器包围它。
尝试以ASCII码打印出从客户端收到的字符串。打印出实际的字符串可能不会显示您可能收到的某些不可打印的字符。