我在查找问题原因时遇到了一些麻烦。
程序的功能如下...... Server
允许多个用户登录(连接到服务器)并使用任一开始命令编辑名为text
的相同字符串变量{ {1}}(用于替换整个字符串)或rep:
(附加到字符串)。
当客户端连接时,他们必须输入命令。无论命令是什么,它都会在同一个窗口中回显给它们(在不同的CMD窗口中同时运行服务器和客户端)。因此,如果他们输入app:
,则回音将为hello
。
如果输入的命令是ECHO: hello
,则服务器中的rep:tight
字符串变量应更改为包含text
,然后应返回/显示在客户端cmd窗口中{ {1}} - 没有ECHO。
如果之后的命令是tight
,则服务器中的tight
字符串变量应更改为包含app:rope
,并应返回/显示在客户端cmd窗口中{ {1}}。
此外,用户不能输入4个字符以下的任何值,因此SynchClient应显示错误消息并提示用户输入其他值。
我遇到的问题是每次新输入后我的回显值都没有改变。我得到了第一个输入命令的返回,就是这样,我正在努力让我全神贯注。
编辑:如果你自己运行该程序,可能是最好的。
以下是我的SynchServer.java文件:
text
和我的SynchClient.java文件:
tightrope
编辑2: 我的工作解决方案:
服务器:
tightrope
客户端:
import java.io.*;
import java.net.*;
import java.util.*;
public class SynchServer
{
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
final int PORT = 1234;
Socket client;
ClientHandler handler;
try
{
serverSocket = new ServerSocket(PORT);
}
catch (IOException ioEx)
{
System.out.println("\nUnable to set up port!");
System.exit(1);
}
System.out.println("\nServer running...\n");
do
{
//Wait for client.
client = serverSocket.accept();
System.out.println("\nNew client accepted.\n");
handler = new ClientHandler(client);
handler.start();
}while (true);
}
}
class ClientHandler extends Thread
{
private Socket client;
private Scanner input;
private PrintWriter output;
private static String text = "";
public ClientHandler(Socket socket) throws IOException
{
client = socket;
input = new Scanner(client.getInputStream());
output = new PrintWriter(client.getOutputStream(),true);
}
public void run()
{
String head, tail, received;
received = input.nextLine();
head = received.substring(0, 4);
tail = received.substring(4);
while (!received.equals("QUIT"))
{
if (head.equals("rep:"))
changeText(tail);
else
if (head.equals("app:"))
appendText(tail);
output.println(text);
output.println("ECHO: " + received);
}
try
{
System.out.println("Closing down connection...");
client.close();
}
catch(IOException ioEx)
{
System.out.println("* Disconnection problem! *");
}
}
private synchronized void changeText(String changedText)
{
text = changedText;
}
private synchronized void appendText(String appendedText)
{
text += appendedText;
}
}
答案 0 :(得分:5)
这主要与static
字段无关。你的错误就在这个循环中:
while (!received.equals("QUIT")) {
if (head.equals("rep:"))
changeText(tail);
else if (head.equals("app:"))
appendText(tail);
output.println(text);
output.println("ECHO: " + received);
}
它在第一次客户端输入后无限运行,并且每次都不从输入流中读取新值。
这些行:
received = input.nextLine();
head = received.substring(0, 4);
tail = received.substring(4);
应该放入循环中:
while (!received.equals("QUIT")) {
received = input.nextLine();
head = received.substring(0, 4);
tail = received.substring(4);
...
<强>更新强>:
确切地说,它有另一个次要问题,这两行:
output.println(text);
output.println("ECHO: " + received);
他们应该改为:
output.println("ECHO: " + text);
(否则你发送两条不同的线路。)
答案 1 :(得分:2)
您有一个同步块,它分别应用于每个对象,而不是每个对象,因为synchronized块适用于不是整个类的对象。
您可以使用静态锁,以便所有客户等待轮到他们。检查此链接以查看静态锁定和非静态锁定之间的比较
Static versus non-static lock object in synchronized block
和这个
How to lock a method for a whole class using synchronized?
因此,您应该从static
字段声明中删除text
修饰符:
private String text = "";
在这种情况下,synchronized
和changeText
方法根本不需要appendText
。