Java TCP客户端/服务器通信仅发送第一条消息?

Java TCP客户端/服务器通信仅发送第一条消息?,java,android,tcp,Java,Android,Tcp,我正在用java设置一个简单的TCP客户机-服务器交互 服务器: 服务器是用Java编写的桌面客户端: import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; class TCPServer { public static int PORT_

我正在用java设置一个简单的TCP客户机-服务器交互

服务器: 服务器是用Java编写的桌面客户端:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

class TCPServer
{
    public static int PORT_NUMBER = 6129;

    public static void main(String argv[]) throws Exception
    {
        String clientMessage;
        ServerSocket welcomeSocket = new ServerSocket(PORT_NUMBER);

        while (true)
        {
            Socket connectionSocket = welcomeSocket.accept();

            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());

            clientMessage = inFromClient.readLine();

            System.out.println("Received: " + clientMessage);

            outToClient.writeBytes("I received this: "+ clientMessage +"\n");
        }
    }
}

客户端: 客户端是一个android应用程序,通过TCP连接到服务器。在客户端中,我有一个方法
sendMessage(stringmsg)
,它试图向服务器发送消息

public static void sendMessage(String msg) throws IOException
{
    if (mainSocket == null)
    {
        return;
    }
    if (!mainSocket.isConnected())
    {
        connectSocket();
    }
    PrintWriter output = new PrintWriter( mainSocket.getOutputStream());
    output.println(msg);
    output.flush();
    System.out.println(msg);
}
问题是,服务器接收到第一条消息,但任何后续消息都不会显示。当我关闭客户机时,所有其他消息都会立即显示在服务器上

public static void sendMessage(String msg) throws IOException
{
    if (mainSocket == null)
    {
        return;
    }
    if (!mainSocket.isConnected())
    {
        connectSocket();
    }
    PrintWriter output = new PrintWriter( mainSocket.getOutputStream());
    output.println(msg);
    output.flush();
    System.out.println(msg);
}
这是服务器看到的:

Received: message 1
长时间没有活动…
然后我关闭了客户

Received: message 2 message 3 message 4 message 5 etc..

我在sendMessage()方法中放入了println,该方法本身正在被实时调用

每次发送消息时,您都需要在客户端显式地
close()
您的
PrintWriter
。当您完成了对
INFOROMCLIENT
的读取,以及对
outToClient
的写入时,服务器端也会发生同样的情况

另请参见此,他们很好地解释了基本工作流程:

但是,基本原理与本课程中的基本原理基本相同:

打开插座

打开套接字的输入流和输出流

根据服务器的协议读取和写入流

关闭溪流

合上插座


sendMessage
方法是从什么上下文运行的?它是来自在UI线程上运行的
活动
,还是来自在非UI线程上运行的某个类?sendMessage是从主UI线程内活动中的onKeyUp事件调用的。这需要在它自己的线程中吗?我有一个类似的问题,是由坏线程引起的,但答案似乎是正确的;)令人惊叹的。我在PrintWriter和套接字上显式调用了close(),现在它可以工作了。我没有意识到close()不是自动隐式调用的。谢谢@这个答案是不正确的。您需要在每次发送邮件时刷新PrintWriter,并在对话完成后关闭它。在每条消息之后关闭它会强制每条消息都有一个新的连接,这是非常奢侈的。好吧,在我的原始代码中,我在每条发送消息之后都有一个
flush()
,没有关闭printWriter或socket,但它显示了我描述的问题。您知道这可能是什么原因吗?因为看起来您只刷新了客户端。但是您还必须在服务器端刷新。EJP是正确的,为每条消息重新打开一个新的连接不是最优雅的方式,但它仍然有效。您也可以尝试保持连接打开,每次特定消息“完成”时两边刷新。我的服务器的编写方式似乎是为每个连接接收一条消息而设计的。我在无限while循环中放置了一个内部循环,该循环在while(connectionSocket.isConnected()){//listen for message}中运行。当插座不再连接时,它将返回到侦听模式。