Java双向套接字连接(服务器/客户端)

4

我希望做的是将一些JSON数据从安卓手机发送到Java服务器,这个过程运行良好。安卓/客户端代码如下:

                    Socket s = new Socket("192.168.0.36", 12390);
                s.setSoTimeout(1500);

                JSONObject json = new JSONObject();
                json.put("emergency", false);
                json.put("imei", imei);
                json.put("lat", l.getLatitude());
                json.put("lon", l.getLongitude());
                json.put("acc", l.getAccuracy());
                json.put("time", l.getTime());


                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
                        s.getOutputStream()));
                out.write(json.toString());
                out.flush();
                s.close();

服务器端是这样的:
        try {
        s = new ServerSocket(port);
    } 
    catch (IOException e) {
        System.out.println("Could not listen on port: " + port);
        System.exit(-1);
    }


    Socket c = null;
    while (true) {
        try {
            c = s.accept();
        } catch (IOException e) {
            System.out.println("Accept failed: " + port);
            System.exit(-1);
        }
        try {

            BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
                String inputLine = null;
            String result = "";
            while ((inputLine = in.readLine()) != null) {
                result = result.concat(inputLine);  
            }
            System.out.println(result);

如我所说,所有这些都是有效的。现在我想在从客户端接收到消息后向服务器发送一条消息。我扩展了代码,如下,Android/客户端:

                    Socket s = new Socket("192.168.0.36", 12390);
                s.setSoTimeout(1500);

                JSONObject json = new JSONObject();
                json.put("emergency", false);
                json.put("imei", imei);
                json.put("lat", l.getLatitude());
                json.put("lon", l.getLongitude());
                json.put("acc", l.getAccuracy());
                json.put("time", l.getTime());


                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
                        s.getOutputStream()));
                out.write(json.toString());
                out.flush();

                String inputLine = null;
                String result = "";
                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
                while ((inputLine = in.readLine()) != null) {
                    Log.d(TAG, in.readLine());
                    result = result.concat(inputLine);
                }

在服务器端:

        try {
    s = new ServerSocket(port);
} 
catch (IOException e) {
    System.out.println("Could not listen on port: " + port);
    System.exit(-1);
}


Socket c = null;
while (true) {
    try {
        c = s.accept();
    } catch (IOException e) {
        System.out.println("Accept failed: " + port);
        System.exit(-1);
    }
    try {

        BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
            String inputLine = null;
        String result = "";
        while ((inputLine = in.readLine()) != null) {
            result = result.concat(inputLine);  
        }
        System.out.println(result);

    PrintWriter out = new PrintWriter(c.getOutputStream());
    out.write("Hello phone");
    out.flush();
    out.close();

在客户端,没有任何信息进来,它会停在那里。
                while ((inputLine = in.readLine()) != null) {
                Log.d(TAG, in.readLine());
                result = result.concat(inputLine);
            }

直到套接字超时(从未进入循环)。我认为这可能是一个时间问题,例如服务器过早发送其回复,因此客户端永远不会收到任何东西,但我尝试在代码中的几乎任何地方都放置out.write("Hello phone");,结果始终相同。它是否与从ServerSocket获取套接字并无法发送数据有关?我错过了什么,这一整天都在困扰我...
编辑:在Nikolais的答案之后,我尝试了这个(客户端):
                    out.write(json.toString());
                out.newLine();
                out.write("###");
                out.flush();


                String inputLine = null;
                String result = "";
                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
                while ((inputLine = in.readLine()) != null) {
                    if (inputLine.contains("###")) {
                        break;
                    }
                    Log.d(TAG, in.readLine());
                    result = result.concat(inputLine);

                }


                s.close();

和服务器:

                while ((inputLine = in.readLine()) != null) {

                result = result.concat(inputLine);  
                if (inputLine.contains("###")) {
                    System.out.println("received ###");
                    out.println("Hello phone");
                    out.println("###");
                    out.flush();
                    break;
                }

            }

这个想法是在客户端关闭socket之前从服务器发送消息。但仍然无法正常工作...有什么提示吗?

1个回答

3
在服务器端,你永远无法发送你的“Hello phone”,直到客户端关闭套接字时才可以发送,但此时已经没有用处了。这是因为in.readLine()会阻塞,直到数据可用或EOF,即套接字关闭。
你需要一种方法来跳出读取循环-发明(或采用)一些应用级协议,告诉你已经接收到了完整的消息。常见的选项有固定长度消息、长度前缀、分隔符等。

完全有道理,谢谢。也许你可以看一下我编辑过的问题,我认为这大致是你想表达的意思吧? - fweigl
@user804967 - 在你的特殊代码后发送一个换行符,否则另一端的readLine()将不会返回。 - jtahlborn
1
在客户端,您需要使用Log.d(TAG, in.readLine());消耗掉一个额外的行 - 这会吃掉您的###标记。 - Nikolai Fetissov
好主意,我删掉了那行代码,但我从未进入过那个循环。如果那行代码有消耗任何东西,它应该会在logcat中显示出来。 很抱歉打扰你们,但你们有想法,而我完全没有想法。 - fweigl
嗯,你可能希望在将信息发送给客户端后继续在服务器上进行阅读循环。否则套接字会关闭。 - Nikolai Fetissov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接