当前位置: 首页 > 知识库问答 >
问题:

Java'SyncServer'允许两个用户同时编辑字符串变量

阙庆
2023-03-14

我找不到问题的原因。

该程序的功能如下...< code >服务器允许多个用户登录(连接到服务器)并使用< code>rep:(用于替换整个字符串)或< code>app:(用于追加到字符串)的启动命令编辑名为< code>text的相同字符串变量。

当客户端连接时,他们必须输入命令。无论命令是什么,它都会在同一个窗口中回显给它们(在不同的CMD窗口中同时运行服务器和客户端)。因此,如果他们输入hello,回声将是echo:hello

如果输入的命令是rep: ready,则服务器中的text字符串变量应更改为包含,然后应返回/在客户端cmd窗口中显示为-没有ECHO。

如果之后的命令是< code>app:rope,则服务器中的< code>text字符串变量应更改为包含< code>tightrope,并且应作为< code>tightrope返回/显示在客户端cmd窗口中。

此外,用户不能输入少于 4 个字符的任何值,因此 SynchClient 应显示一条错误消息并提示用户输入另一个值。

我遇到的问题是,我的回声值在每次新输入后都没有改变。我得到第一个输入的命令的返回,仅此而已,我正在努力解决这一切。

编辑:如果您自己运行该程序,可能是最好的。

以下是我的同步服务器.java文件的外观:

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;
    }
}

还有我的SynchClient.java档案:

import java.io.*;
import java.net.*;
import java.util.*;

public class SynchClient
{

    public static void main(String[] args) throws IOException
    {
        InetAddress host = null;
        final int PORT = 1234;
        Socket socket;
        Scanner networkInput,keyboard;
        PrintWriter output;

        try
        {
            host = InetAddress.getLocalHost();
        }
        catch(UnknownHostException uhEx)
        {
            System.out.println("\nHost ID not found!\n");
        }

        socket = new Socket(host, PORT);
        networkInput = new Scanner(socket.getInputStream());
        output = new PrintWriter(socket.getOutputStream(),true);

        keyboard = new Scanner(System.in);

        String message, response;

        do
        {   
            System.out.print("\nEnter message ('QUIT' to exit): ");
            message = keyboard.nextLine();

            if (message.length() < 4)
            {
                System.out.print("\nPlease enter a value greater than 4 characters: ");
                message = keyboard.nextLine();
            }

            output.println(message);

            if (!message.equals("QUIT"))
                {
                    response = networkInput.nextLine();
                    System.out.println("\n" + response);
                }
        }while (!message.equals("QUIT"));

        try
        {
            System.out.println("\nClosing down connection...\n");
            socket.close();
        }
        catch(IOException ioEx)
        {
            System.out.println("\n* Disconnection problem! *\n");
        }
    }
}

编辑2:我的工作解决方案:

服务器:

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();

        // create head and tail in case first input is rep: or app:
        head = received.substring(0, 4);
        tail = received.substring(4);

        while (!received.equals("QUIT"))
        {
            if (head.equals("rep:"))
            {
                changeText(tail);
                output.println(text);
                // input for next one
            }
            else
                if (head.equals("app:"))
                {
                    appendText(tail);
                    output.println(text);
                    // get input for next
                }
            else
            {
                //must be some random thing that just needs to be echoed
                output.println(text);
            }

            //Get next input
            received = input.nextLine();
            //and set the head and tail again
            head = received.substring(0, 4);
            tail = received.substring(4);
        }

        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;
    }
}

客户:

public class SynchClient
{

    public static void main(String[] args) throws IOException
    {
        InetAddress host = null;
        final int PORT = 1234;
        Socket socket;
        Scanner networkInput,keyboard;
        PrintWriter output;

        try
        {
            host = InetAddress.getLocalHost();
        }
        catch(UnknownHostException uhEx)
        {
            System.out.println("\nHost ID not found!\n");
        }

        socket = new Socket(host, PORT);
        networkInput = new Scanner(socket.getInputStream());
        output = new PrintWriter(socket.getOutputStream(),true);

        keyboard = new Scanner(System.in);

        String message, response;

        do
        {
            System.out.print("\nEnter message ('QUIT' to exit): ");
            message = keyboard.nextLine();

            while (message.length() < 4)
            {
                System.out.print("\nPlease enter 4 or more characters: ");
                message = keyboard.nextLine();
            }

            output.println(message);
            if (!message.equals("QUIT"))
            {
                response = networkInput.nextLine();

                System.out.println("\n" + response);
            }

        }while (!message.equals("QUIT"));

        try
        {
            System.out.println("\nClosing down connection...\n");
            socket.close();
        }
        catch(IOException ioEx)
        {
            System.out.println("\n* Disconnection problem! *\n");
        }
    }
}

共有2个答案

屈畅
2023-03-14

您有一个单独应用于每个对象而不是每个对象的同步块,因为同步块应用于对象而不是整个类。

您可以使用静态锁,因此所有客户端都等待轮到它们。检查此链接以查看静态锁和非静态锁之间的比较

同步块中静态与非静态锁对象

还有这个

如何使用synchronized为整个类锁定一个方法?

因此,您应该从text字段声明中消除静态修饰符:

private String text = "";

在这种情况下,您根本不需要为更改文本追加文本方法同步

朱宏爽
2023-03-14

这根本不主要是关于< code >静态字段。你的错误在这个循环中:

       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);

(否则,您会发送两个不需要的单独的行)。

 类似资料:
  • 问题内容: 我正在使用Base64编码来编码Java中的用户ID字段。 我想知道上面的字符串abc是否包含字符“,:”吗? 当以abc返回Base64编码的字符串时,它是否会包含以下字符? 问题答案: 您不会在Base64编码的字符串中看到任何逗号,冒号或双引号。由于等号用于填充结尾内容,因此您会看到等号。

  • 但是,这并不适用于String类。请参见下面的代码: 这是因为字符串类和自声明类之间的差异吗?谢谢你的帮助!

  • 我正在处理一个电话号码正则表达式,这是我到目前为止所拥有的: 它允许0到9之间的数字,也允许''和空白。范围必须在8到20之间。这工作罚款。 我想进一步得到的是,只有8到20个数字,其中“”和空格是分开的。 类似这样的内容: 建议?

  • > 当同一主机上的两个进程使用网络套接字通信时,它们的套接字必须使用不同的端口吗? 我想是的,因为套接字由IP地址和端口号标识。如果进程的套接字使用相同的端口,则无法区分它们的套接字,对吗? 但是一个主机可以有多个网络接口,所以有多个IP地址。同一个主机上的多个网络接口是否可以共享一个端口,从而使两个套接字共享同一个端口? 例如,SSH本地端口转发由以下选项指定: 然后本地主机(SSH客户端运行的

  • 我有一张excel表格,里面有一些时间值。这些值是格式化为字符串的持续时间。当我尝试对这些值求和时,结果是0,因为Excel不能对字符串求和。当我点击公式栏上的回车键时,它确实变成了一个时间,所以我计算出的总和是有效的。如何将单元格的值从字符串更改为时间值?我已经将日期格式设置为和 我从转换成秒的时间量开始,我将其转换成持续时间 然后我使用 然后我将单元格值设置为刚刚生成的字符串 然后我将设置为一

  • 问题内容: 我在这里的研究中得到了不同的答案。 有人可以验证Redis服务器只能存储任何数值的表示吗? 例如,如果我在lpush中使用具有双重类型的Java客户端(Jedis),在发送给Redis之前是否需要将其转换为等效于字符串类型的内容? 还是有一种方法可以发送诸如double之类的实际数字类型?如果是这样,是否有任何示例代码说明了如何实现此目的? 谢谢 问题答案: Redis将所有内容存储在