【问题标题】:Java - TCP/IP - Server can't send message back to Client?Java - TCP/IP - 服务器无法将消息发送回客户端?
【发布时间】:2018-02-26 18:27:32
【问题描述】:

我想将一个对象从我的客户端发送到我的本地主机服务器以添加到数据库中,并将结果发送回该对象是否发送成功。对象已成功发送,但我的服务器没有将结果发送回客户端,并导致我的客户端框架表单因等待服务器响应而挂起。我不知道我的代码有什么问题。你能告诉我一些解决这个问题的方法吗?

这是发送结果的函数:

public void sendResult(String result) {
    try {
        Socket clientSocket = myServer.accept();
        System.out.println("Connected to client");
        ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());

        os.writeObject(result);
        System.out.println("Result sent");
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

调用发送结果函数的地方:

public void service() {
    try {
        if (receiveStudent() != null) {
            Student std = receiveStudent();
            if (dao.addStudent(std)) {
                System.out.println("OK");
                sendResult("OK");
            } else {
                System.out.println("FAILED");
                sendResult("FAILED");
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

另外,在Service函数中,控制台打印“OK”,表示满足if条件。

接收学生方法:

public Student receiveStudent() {
    Student s = new Student();

    try {
        Socket clientSocket = myServer.accept();
        System.out.println("Connect to client successfully");
        ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());

        Object o = ois.readObject();
        if (o instanceof Student) {
            s = (Student) o;
            return s;
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

【问题讨论】:

  • 显示 ReceiveStudent() 方法的代码
  • sendResult() 方法等待客户端连接到它,因为accept()。应该反过来,服务器应该连接到客户端。
  • @LucianovanderVeekens 这意味着我必须再次将客户端重新连接到服务器?
  • @BrotherEye 你应该重用你在receiveStudent() 中获得的clientSocket 来发回响应。
  • @LucianovanderVeekens 我注意到您的评论,并将客户端套接字作为服务器类的属性添加为全局变量,现在可以使用。非常感谢!但是现在我必须重新输入两次表格才能成功添加对象。这是某种延迟还是我的代码有问题?

标签: java tcp


【解决方案1】:

由于sendResult() 中的myServer.accept(),服务器再次等待传入的客户端连接,而这已经在receiveStudent() 中发生。重复使用该连接。

共享您在receiveStudent() 中获得的客户端套接字,例如,将其转换为字段。

public Student receiveStudent() {
    ...

    try {
        clientSocket = myServer.accept();
        ...
    } catch (Exception ex) {
        ...
    }
    ...
}

然后在sendResult() 中重用该套接字以将结果发送给客户端。

public static void sendResult(String result) {
    try {
        ...
        ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
        ...
    } catch (Exception ex) {
        ...
    }
}

【讨论】:

  • 我注意到您在上面对此解决方案的评论并完成了它,它现在可以工作了。非常感谢!
  • 您不希望服务器连接到客户端。 客户端连接到服务器。服务器接受连接来自客户端。答案毫无意义。
  • @EJP 你是对的。改了一点,写的不好。
【解决方案2】:

如果你想发送一个字符串作为对象,你为什么不直接使用这样的东西:

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); //for sending String messages
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); //for getting String messages

...然后当您需要发送时,您可以这样做:

out.println(textToServer");  // send to server - don't forget LN in println.
out.flush(); // to clean buffer

它应该做你需要做的事情。
并确保您的客户端类正在等待获取您发送的InputStream,不要忘记这一点,因为这可能是客户端的问题。
也许客户端不接受传入的Socket,无论是ObjectInputStream 还是BufferedReader 都会接受传入的套接字对象。

您可以为我们提供一个 Client 类,以便我们查看是否缺少对传入套接字的接受。

确保在方法结束时关闭流和套接字。

out.close();
in.close();
socket.close();

更多详情请查看thisthisthis。希望对您有所帮助:)

【讨论】:

  • 这是个好主意。但我认为我的问题是服务器套接字和客户端套接字之间的连接。如果它们没有连接,那么无论您使用什么方法发送数据,它们都不会接收到。我已将客户端套接字设为全局变量,而不是在 sendResult 方法中创建本地变量,现在它可以工作了。
  • 那你检查过你的server和socket之间的连接了吗?当您使用 ServerSocket 设置服务器并接受客户端时,您是否使用正确的端口将客户端连接到服务器? ServerSocket welcomeSocket = new ServerSocket(1234);
    Socket clientSocket = new Socket("localhost", 1234);
    能否请您提供完整代码或仅提供服务器和客户端类?
  • 我向您保证它们已连接到正确的主机和端口。我想我通过在发送结果方法中创建一个新的客户端套接字,不小心将我的服务器套接字连接到了我想要连接的客户端套接字。
【解决方案3】:

您拨打了两次accept()。这是没有意义的。您需要:

  1. 接受连接。这会返回一个Socket
  2. 读取请求并创建响应。
  3. 通过您在 (1) 中接受的同一 Socket 发送响应。

希望为每个接受的套接字创建一个新线程,并且您还希望在该线程中执行所有 I/O,包括创建ObjectInputStreamObjectOutputStream。否则,您的服务器不是正确的多线程和多客户端。

【讨论】:

  • 谢谢!我已将客户端套接字转换为全局变量并解决了问题
猜你喜欢
  • 2019-12-06
  • 2016-05-25
  • 2013-04-29
  • 2017-04-03
  • 2017-05-03
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 2011-05-12
相关资源
最近更新 更多