【问题标题】:java socket disconnected from server sidejava socket与服务器端断开连接
【发布时间】:2012-05-07 09:36:52
【问题描述】:

我遇到了有关服务器端套接字的问题。我的代码是客户端。每当我发送第二条消息(无论是心跳消息还是任何其他消息)时,它都会在服务器上失败,并且服务器端会记录一个“消息格式错误”,但相同的消息第一次会成功。 这个你能帮我吗。 我的客户代码:

    public class Main {

        String Host = "";
        int port = 1111;
        Socket ss;
        BufferedReader in;
        BufferedWriter out;
        String recv;

        public void connection() {
            try {

                ss = new Socket(Host, port);
                ss.setSoTimeout(30000);

                in = new BufferedReader(new InputStreamReader(ss.getInputStream()));
                out = new BufferedWriter(new OutputStreamWriter(ss.getOutputStream()));

            } catch (UnknownHostException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        public void sender(String regTag) {

            if (ss == null || !ss.isConnected()) {
                connection();
            }
            try {

                if (out != null && regTag != null) {
                    out.write(regTag + "\n");
                    System.out.println("message::" + regTag);
                    out.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public String Reciver() {

            try {

                recv = in.readLine();
                if (ss != null && recv != null) {
                    return recv;
                } else {
                    disconnect();
                    String Str = "nothing...Sorry";
                    return Str;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "Exception";
            }
        }

        public void disconnect() {
            try {
                System.out.println("socket discoonected.");
                ss.close();
                in.close();
                out.close();
                connection();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) {


            Main me = new Main();
            me.connection();
            String hbhb = "`SC`0004HBHBB7BDB7BD";
            String login = "`SC`00581.000000CRBTSRVM    00000001DLGLGN    00000002 TXBEG    LOGIN:USER=cvbs,PSWD=password   DEB2CCA8";
            String cut = "`SC`00631.000000CRBT00PPSPHS00000002DLGCON    00000003 TXBEG    CUT PPS FEE:MDN=9610023,CUTFEE=1000,REASON=1   BDB7DA88";
            me.sender(hbhb.trim());
            String str = me.Reciver();
            System.out.println("Response :::" + str);
            me.sender(login.trim());
            String str1 = me.Reciver();
            System.out.println("Response hb:::" + str1);
}

它在每第二条消息上一直收到 null ...

来自服务器端的日志

[121_SERVER] 2012-05-03 14:26:37:213 [ERROR] [ServerAccptor.java:254] ->
errorCode = [UIP-80015] errorDesc = [Uip server has a exception when receiving data from the client,will remove the client,Server [adapter id=121],.]
        at com.ztesoft.zsmart.bss.uip.adapter.socket.server.ServerAccptor.listenMsg(ServerAccptor.java:252)
        at com.ztesoft.zsmart.bss.uip.adapter.socket.server.ServerAccptor.run(ServerAccptor.java:117)
Caused by: errorCode = [UIP-9102] errorDesc = []  Describing= [read client message error,will remove client.]
        at com.ztesoft.zsmart.bss.uip.adapters.socket.server.mml.MMLServerAdapter.readByteField(MMLServerAdapter.java:784)
        at com.ztesoft.zsmart.bss.uip.adapters.socket.server.mml.MMLServerAdapter.reciveWholeMsg(MMLServerAdapter.java:671) 

【问题讨论】:

  • 我们可以看到堆栈跟踪吗?一些服务器代码?这会有所帮助。
  • 你有关于服务器协议的详细信息吗?发送 '\n' 后似乎没有其他任何期望
  • “服务器失败”。请翻译成实际的错误消息,最好是完整的堆栈跟踪。
  • @tulsi 从代码中不言而喻这是TCP,没有人问过这个问题。请回答您实际被问到的问题。

标签: java sockets


【解决方案1】:

您的代码包含许多不良做法和谬误。

  1. 您正在记录异常并以其他方式忽略它们,并做一些奇怪的事情,例如让程序继续运行、返回“异常”等。这是糟糕的编程。有例外可以帮助您,而不是用创可贴来隐藏血液。代码在创可贴下不会自我修复。例如,您应该只声​​明connection() 以抛出IOException 并让调用者处理它。

  2. 由于 (1) 您有许多 ss != null 测试。您甚至不应该处于需要执行 I/O 的状态,ss 可能是null。再次正确的异常处理和传播将避免这种情况。

  3. 作为 (1) 的进一步结果,您有许多 !ss.isConnected() 测试,显然错误地认为此 API 会告诉您连接是否已断开。它不会。它只会告诉您是否已连接Socket。在您的代码中,当您调用ss = new Socket(...) 时,您已连接它,否则您尚未执行该代码。调用isConnected() 没有任何价值。

  4. 您在输出流之前关闭了套接字输入流。这是不正确的。您应该关闭输出流,并在 finally 块中关闭套接字本身。这样输出流就会被刷新。关闭输入流会关闭套接字和输出流而不刷新它。不要那样做。

【讨论】:

    【解决方案2】:

    其实正确答案是MML响应中没有\n。所以这永远行不通:

    recv = in.readLine();   
    

    您必须阅读响应的消息头部分中给出的消息长度并读取到该长度。

    更新:

    1. 您的MML 命令中有语法错误。看来您使用的是 1.00 版本的协议,所以这是一个有效的示例(寻找差异):

      `SC`00741.00CRBT    PPS     00000001DLGCON    00000004TXBEG     PPS CUT FEE:mdn=93784050910,fee=300,id=20140812165011003    F3E0ADDF
      

    您必须在数字中用0 填充多余的空格,在其他地方您必须用空格填充它们。

    【讨论】:

    • 这并不能解释为什么服务器在读取请求时会抛出异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2015-05-17
    • 2014-04-01
    • 2013-08-26
    • 2010-12-07
    • 2013-03-31
    相关资源
    最近更新 更多