【问题标题】:TCP message not received more than 1 timeTCP 消息未收到超过 1 次
【发布时间】:2012-09-23 17:17:07
【问题描述】:
class SomeUI     
{ 
SocketMessageSender messageSender; 
// ensure that its initialized ... 
private void bSendMessageActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            // TODO add your handling code here:
            messageSender.sendMessage(jMessage.getText()); 
            jMessage.setText("");
        } catch (IOException ex) {
            Logger.getLogger(TeKServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    } 
}

错误:线程“AWT-EventQueue-0”中的异常 java.lang.RuntimeException:无法编译的源代码 - 错误的符号类型:bSendMessageActionPerformed

【问题讨论】:

  • 服务器代码是做什么的?
  • 服务器代码工作得很好,因为我也在 PHP 端进行了测试,服务器接收来自客户端的来电并显示在服务器聊天中
  • 这些都不应该在 actionPerformed 方法中完成。他们不应该执行阻塞操作。
  • 那么你建议我应该在哪里制作它,主要是?因为如果我在 main 中使用它,我将无法使用 String process = jMessage.getText();如果我在 run() 中成功,我的应用程序将由于 TCP 连接而冻结(?)
  • 您的问题与您的服务器代码有关,您不准备展示您的服务器代码..?

标签: java tcp client


【解决方案1】:

为什么每次单击按钮时都打开套接字并关闭它。创建一个类,允许您在应用程序运行时保持套接字打开。应用启动时就可以进行socket连接了,可以试试下面这个类

public class SocketMessageSender
{
    private String host;
    private int port;
    private DataOutputStream dos;

    public SocketMessageSender(String host, int port)
    {
        this.host = host;
        this.port = port;
    }

    // call when application starts
    public void initConnection() throws IOException
    {
        InetAddress address = InetAddress.getByName(host);
        Socket connection = new Socket(address, port);
        dos = new DataOutputStream(connection.getOutputStream());
    }

    //call from button click
    public void sendMessage(String message) throws IOException
    {
        if(dos != null)
        {
            dos.writeUTF(message);
            dos.flush();
        }
    }

    // call when application exits
    public void closeConnection() throws IOException
    {
        if(dos!= null)
        {
            dos.close();
        }
    }
}

希望对你有帮助...

假设你有一个像

这样的类
class SomeUI
{
   SocketMessageSender messageSender;
   // ensure that its initialized ...



 private void bSendMessageActionPerformed(java.awt.event.ActionEvent evt) {
    messageSender.sendMessage(jMessage.getText());
    jMessage.setText("");
 }
}

我认为类签名应该是这样的......

public class MyPanel extends JPanel implements ActionListener
{
    private SocketMessageSender messageSender;
    private Message jMessage = new Message();// This is just a temp class, replace this with your class

    public MyPanel()
    {
        messageSender = new SocketMessageSender("some host", 8080);
        try
        {
            messageSender.initConnection();
        }
        catch(IOException e)
        {
             Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        try {
            // TODO add your handling code here:
            messageSender.sendMessage(jMessage.getText()); 
            jMessage.setText("");
        } catch (IOException ex) {
            Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

【讨论】:

  • 谢谢,这正是我所需要的……帮了很多忙。另外,如果您能告诉我,上面的代码如何知道单击按钮的时间?我的意思是在 sendMessage 中我应该添加 onClickListener 吗?
  • 它给了我这个错误:线程“AWT-EventQueue-0”中的异常java.lang.RuntimeException:无法编译的源代码 - 错误的符号类型:bSendMessageActionPerformed
  • 可以分享一下你的源码吗,完整的课就好了。
  • 这里:pastebin.com/8QFFM2ci 如果这段代码看起来有点混乱(因为我使用了 jframe,但在代码中你会看到按钮的初始化和可能使代码看起来有点混乱的东西请让我知道我会尝试 ogranise 这一切
  • 我要去吃午饭了,请允许我 15 分钟,我会马上回来为您提供帮助我解决此问题所需的一切:D
【解决方案2】:

考虑使用 ObjectOutputStream/ObjectInputStream 并通过套接字写入对象。 java2s.com上有很多例子

请注意,如果您多次写入同一个对象,您需要在写入之前 reset() 流,然后刷新。

【讨论】:

  • 怎么回事?抱歉,我是 java 新手,如果您能制作示例代码,我会很高兴
猜你喜欢
  • 2015-11-23
  • 2020-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 2018-05-15
相关资源
最近更新 更多