我正在尝试用Java编写控制台客户端 - 服务器应用程序;使用套接字,我目前有一个简单的登录系统和一个简单的命令系统。登录系统似乎正常工作,连接似乎正常。
但是,命令系统似乎根本不起作用,当服务器收到命令时,它似乎没有发回任何内容。
所以我的主要问题是为什么我的服务器在收到命令时不会向客户端发回任何内容?
这是我的服务器:
import java.io.*;
import java.net.*;
class TCPServer2
{
public static void main(String argv[]) throws Exception
{
//error is caused by command being used differently to login & username/password strings.
//consider removing command as a set string and adding a statement which takes
//the readLine value, adds it to a string and the command is the value of said string.
//If string is = "listLanguages" do this else if = "getcost" do this else "invalid cmd".
ServerSocket welcomeSocket = new ServerSocket(6789);
Map<String, String> userDetails = new HashMap<String, String>();
userDetails.put("JOHN","UNCP");
userDetails.put("MATT","UNCP");
String Command;
String username;
String username1;
String password;
String password1;
String cmd;
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
username = inFromClient.readLine();
System.out.println("\nUsername received: " + username);
password = inFromClient.readLine();
System.out.println("\nPassword received: " + password);
username1=username.toUpperCase();
password1=password.toUpperCase();
if (userDetails.get(username1).equals(password1))
{
outToClient.writeBytes("Hello " + username1);
outToClient.writeBytes("\nOther users registered on the server currently include: \n");
for (String str : userDetails.keySet())
{
outToClient.writeBytes(str);
}
}
else
{
outToClient.writeBytes("Invalid Username and/or password.\n");
}
BufferedReader inFromClient2 =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient2 = new DataOutputStream(connectionSocket.getOutputStream());
Command = inFromClient2.readLine();
System.out.println("\nCommand received: " + Command);
if(Command.equals("listTranslations"))
{
outToClient2.writeBytes("English,Thai,Geordie,etc.");
}
else
{
if(Command.equals("getCost"))
{
outToClient2.writeBytes("£100\n");
}
else
{
outToClient2.writeBytes("Invalid Command");
}
}
}
}
}
这是我的客户:
import java.io.*;
import java.net.*;
class TCPClient2
{
public static void main(String argv[]) throws Exception
{
String userName;
String passWord;
String loginInfo;
String loginInfo2;
String loginInfo3;
String command;
String commandInfo;
String commandInfo2;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Username: ");
userName = inFromUser.readLine();
outToServer.writeBytes(userName + "\n");
System.out.println("Password: ");
passWord = inFromUser.readLine();
outToServer.writeBytes(passWord + "\n");
loginInfo = inFromServer.readLine();
System.out.println(loginInfo);
loginInfo2 = inFromServer.readLine();
System.out.println(loginInfo2);
loginInfo3 = inFromServer.readLine();
System.out.println(loginInfo3);
System.out.println("Please enter a command: ");
command = inFromUser.readLine();
outToServer.writeBytes(command);
commandInfo = inFromServer.readLine();
System.out.println(commandInfo);
commandInfo2 = inFromServer.readLine();
System.out.println(commandInfo);
clientSocket.close();
}
}
以下是它应该如何工作: 客户端连接到服务器, 客户端要求用户登录, 用户输入他的登录信息, 服务器检查登录信息, 服务器告诉客户端它已成功登录, 客户端要求用户输入命令, 用户输入命令(以请求价格), 该命令被发送到服务器, 服务器发回所需的信息, 然后它应该循环回到被要求输入命令的用户。
但是,它没有这样做。在用户登录后,在“当前包含在服务器上的其他用户包括:”行中,它会卡住,而不会打印任何数据。
为什么要这样做?
答案 0 :(得分:1)
为什么它被卡住可能是因为客户端和服务器都在readLine()上导致死锁。客户端等待输入数据,服务器也是如此,因为这是命令promt客户端和服务器,并且没有“按钮”来发送数据。
我会添加信息,显示当前正在打印的变量,以便您可以轻松跟踪卡住的位置。例如:
loginInfo = inFromServer.readLine();
System.out.println("loginInfo client Side "+loginInfo);
这将显示它正在打印位于客户端的loginInfo变量。现在,您可以轻松地跟踪流程并找出出错的位置。
我从未完成命令promt服务器/客户端(仅限gui),但是当您使用当前设计打印用户列表时,您可能希望构建包含所有用户名的字符串,将整个字符串发送到到客户端,然后客户端用StringBuilder分隔字符串并打印结果。这是因为客户端不知道服务器将发送多少“用户名”
答案 1 :(得分:0)
您是否尝试在发送下一行之前刷新数据输出流编写器的缓冲区。我也很好奇为什么你为一个客户端使用两个不同的数据输出流编写器和输入流读取器。难道你不能只为程序的两个部分使用相同的部分。
答案 2 :(得分:0)
问题在于套接字数据读取/写入方法不正确。在将数据写入套接字时,必须始终刷新()。如果你评论行
//loginInfo3 = inFromServer.readLine();
//System.out.println(loginInfo3);
然后您可以看到客户端显示“请输入命令”但输入命令后套接字不会被刷新/关闭,因此服务器会一直等待。
服务器和客户端代码的主要问题是正确的握手。您必须在块中编写代码,打开套接字,写入命令,获取响应和关闭套接字。这应该是输入数据的常用方法。你有没有棒球插座并在没有正确冲洗/关闭的情况下将数据写入流中,因此它在不同的点上等待。