Java客户端向服务器发送部分消息,尽管显示为完整消息

时间:2018-03-11 16:03:47

标签: java tcpclient

我有一个用Java编写的客户端和一个用C ++编写的服务器。客户端应该在收到服务器的响应后每5秒发送一条消息,如“MESSAGE | 1 | 2 | 3 | 4 | 5”。

开始连接:

private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream output = null;
private BufferedReader br = null;
private Timer timer;

public void start() 
{
    int timerRate = 5;

    try
    {
        int refreshRate = Integer.parseInt(appSingleton.getRefreshRateShared());
        timerRate = refreshRate;
    }
    catch(NumberFormatException e)
    {
        LOGGER.addLogError("Error converting refresh rate: "+e);
    }

    try
    {
        // Create socket and streams
        socket = new Socket(appSingleton.getIpAddressFullShared(), appSingleton.getIpPortShared());
        input = new DataInputStream( socket.getInputStream());
        output = new DataOutputStream( socket.getOutputStream());

        // Start Timer thread
        executorService = Executors.newSingleThreadScheduledExecutor();

        executorService.scheduleAtFixedRate(new Runnable() 
        {
            @Override
            public void run() 
            {
                // Create new TCP connection if the map is not currently updating
                if(isMapUpdating == false)
                {
                    isMapUpdating = true;

                    communicateWithServer();
                }
            }
        }, 0, timerRate, TimeUnit.SECONDS);
    }
    catch (UnknownHostException e)
    {
        cancelConnection();
    }

    catch (EOFException e)
    {
        cancelConnection();
    }

    catch (IOException e)
    {
        cancelConnection();
    }
}

public void communicateWithServer()
{
    // Create a message to the server
    String messageToServer = makeMessageToServer(); 
    String messageFromServer = connectToClient(messageToServer);

    // Read the message and update panel on the main thread
    SwingUtilities.invokeLater(() ->
    {
        messageReceived(messageFromServer);
    });
}

public String connectToClient(String messageToServer)
{
    String data = "";
    // Message from the server that should terminate TCP connection
    String  terminator = "END_DATA";

    try 
    {
        //Send message to the server
        output = new DataOutputStream( socket.getOutputStream());
        output.writeBytes(messageToServer);

        System.out.println("OUTPUT LENGTH: "+output.size());

        //Read Response
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String s = "";
        int value;

        // Process the message from the server and add to the StringBuilder
        while((value = br.read()) != -1) 
        {
            // converts int to character
            char c = (char)value;

            sb.append(c);

            if(sb.toString().contains(terminator))
            {
                break;
            }
        }

        // Create the final string
        data = sb.toString();
    } 
    catch (IOException e) 
    {
        cancelConnection();
        data = "ERROR";
    }

    return data;
}

private void messageReceived(String message)
{
    // Processing data from server and displaying values on Main Thread

    // Map finished updating when data is processed
    isMapUpdating = false;
}

服务器从客户端获取消息,将其转换为数组,然后进一步处理数据。第一条消息发送得很好。但是,在第二条消息上,服务器崩溃。我检查了发送到服务器的内容,结果是消息是这样的:

“MESSAGE | 1 | 2 | 3 | 4 | 5”

“M”

“ESSAGE | 1 | 2 | 3 | 4 | 5”

因此,服务器在第二个收到的消息上崩溃,因为它无法将其拆分为数组。

当我检查DataOutputStream时,它总是显示正确的大小。

如果有人知道如何修复它,我将不胜感激!

1 个答案:

答案 0 :(得分:0)

好吧,如果您要编写网络软件,双方都需要能够处理数据可能碎片化并一点一点地到达;你通常不会完全控制它。

为了降低风险,请在写入后刷新输出流:

    output = new DataOutputStream( socket.getOutputStream());
    output.writeBytes(messageToServer);
    output.flush();

它告诉流将缓冲的数据写入下一层。