【问题标题】:Not getting response in socket connection在套接字连接中没有得到响应
【发布时间】:2017-04-04 04:13:02
【问题描述】:

我无法在套接字连接中获得响应,并且我无法理解代码有什么问题。 我可以使用 ip 地址和端口号建立套接字连接,并且它正在进入

    if (nsocket.isConnected()) {} 

当我尝试使用 telnet 时,我可以得到响应。但是输入还有一些其他参数,例如:

POST /setMap HTTP/1.1 主机:192.168.1.1 内容类型:应用程序/json;字符集=utf-8 内容长度:1234

{ "cmd":"request_get_file_list","verification":"CVS" }

我不知道如何在我的代码中包含内容类型、长度等连接属性。

代码如下:

public class WebService {

public static String devicelisting() {
    Socket nsocket;

    String response = null;

    try {
        nsocket = new Socket("192.168.1.1", 6666);
        if (nsocket.isConnected()) {

            JSONObject json = new JSONObject();
            json.put("cmd", "request_get_file_list");
            json.put("verification", "CVS");
            Log.i("AsyncTask", "doInBackground: Creating socket");
            // nsocket = new Socket();
             OutputStreamWriter out = new OutputStreamWriter(nsocket.getOutputStream(), StandardCharsets.UTF_8);
                out.write(json.toString());
            Log.i("Webservice", "json.toString"+json.toString());

            InputStream in = new BufferedInputStream(nsocket.getInputStream());
            BufferedReader r = new BufferedReader(new InputStreamReader(in));
            StringBuilder stringbuilder = new StringBuilder();
            String line;
            while ((line = r.readLine()) != null) {
                stringbuilder.append(line);
                Log.i("line", "line.line"+line);
            }


            response = stringbuilder.toString();
            Log.i("Response", response);
        }
        else{
            Log.i("Response", "not connected");

        }

    } catch (ProtocolException e) {
        e.printStackTrace();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return response;
}

请帮我找出问题所在。我被卡住了。请帮我解决问题

【问题讨论】:

  • 也许您可以尝试“数据包捕获”应用程序,看看是否有任何类型的响应您在应用程序中看不到或接收到,但实际上您是通过设备收到的
  • 输入是POST?如果您正在实施 HTTP,则需要在开始之前对 RFC 2616 有很好的了解。太宽泛。 NB Socket.isConnected() 在您测试它时不可能是假的。不要编写无意义的代码。
  • @EJB 对不起,我是套接字连接的新手。那我应该怎么做才能解决这个问题呢?
  • 您能否尝试将此示例与@Haris Qureshi 提供的答案进行比较?您也可以像这样设置超时: mSocket.setSoTimeout(10000);客户端和服务器应用的参考链接,examples.javacodegeeks.com/android/core/socket-core/…

标签: android json sockets


【解决方案1】:

对于套接字驱动的事件,很难实现许多功能,而有一些(开源)库可以实现这样的任务。考虑使用Socket.io

Properties headers = new Properties();
headers.setProperty("Content-Type","application/json"); // your headers
SocketIO socketIO = SocketIO(url, headers);

欲了解更多信息,请查看SocketIO docs

编辑

在您给定的示例中,您应该使用HttpURLConnection,因为您从服务器获得响应,您不需要实现套接字。只需 GETPOST 即可使用 HttpURLConnection 获取或推送您的数据。

【讨论】:

  • 你能为用户的问题提供一些代码吗?您的建议库难以实施
【解决方案2】:

android中的socket连接,可以使用this gist file,简单实现socket连接。

public SocketConnection(OnStatusChanged statusChangedListener, OnMessageReceived messageReceivedListener) {
        mStatusListener = statusChangedListener;
        mMessageListener = messageReceivedListener;

        isRunning = true;
        try {
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
            mStatusListener.statusChanged(WAITING);
            socket = new Socket(serverAddr, SERVER_PORT);
            try {
                printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                mStatusListener.statusChanged(CONNECTED);
                bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while (isRunning) {
                    retrieveMessage = bufferedReader.readLine();
                    if (retrieveMessage != null && mMessageListener != null) {
                        mMessageListener.messageReceived(retrieveMessage);
                    }
                    else {
                        mStatusListener.statusChanged(DISCONNECTED);
                    }
                    retrieveMessage = null;
                }
            } catch (Exception e) {
                mStatusListener.statusChanged(ERROR);
            } finally {
                socket.close();
            }
        } catch (Exception e) {
            mStatusListener.statusChanged(ERROR);
        }
    }

更新

如果您想设置自定义标题,只需将它们写入printWriter

当你写作时

writer.print ("GET " + szUrl + " HTTP/1.0\r\n\r\n"); 

\r\n\r\n 位发送换行符/回车符以结束行,然后发送另一个以指示没有更多标题。这是 HTTP 和电子邮件格式的标准,即空行表示标头的结尾。为了添加额外的标题,您只需要在完成之前不要发送该序列。您可以改为执行以下操作

writer.print ("GET " + szUrl + " HTTP/1.0\r\n"); 
writer.print ("header1: value1\r\n"); 
writer.print ("header2: value2\r\n"); 
writer.print ("header3: value3\r\n"); 
// end the header section
writer.print ("\r\n"); 

【讨论】:

  • 超出范围,@Liya 询问如何添加标题和套接字而不是您回答的内容。
  • @HarisQureshi,检查更新!
【解决方案3】:

代码可能卡在readLine(),因为服务器仍在等待请求完成。

你可以改成:

// query
out.write("POST /setMap HTTP/1.1\r\n");
// headers
out.write("Host: 192.168.1.1\r\n");
out.write("Content-Type: application/json; charset=utf-8\r\n");
out.write("Content-Length: " + json.toString().getBytes(StandardCharsets.UTF_8).length + "\r\n");
// end of the headers
out.write("\r\n");
// body
out.write(json.toString());
// actually send the request
out.flush();

Log.i("Webservice", "json.toString"+json.toString());

我认为您使用了错误的工具来发出 HTTP 请求。套接字是低级的网络通道,很多事情都得自己做。

您应该考虑改用HttpURLConnection。如果可能的话,我强烈建议采用更高级别的方法,例如使用retrofit2 之类的东西。

【讨论】:

    【解决方案4】:

    非常感谢您的每一个回答。所有答案都让我找到正确的答案。我可以解决这个问题,这是代码。

                   myClient = new Socket("192.168.1.1", 6666);
    
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("cmd", "request_get_file_list");
                    jsonObject.put("verification", "CVS");
    
                    myClient.setKeepAlive(true);
                    try {
    
                        DataInputStream dis = new DataInputStream(myClient.getInputStream());
                        DataOutputStream dos = new DataOutputStream(myClient.getOutputStream());
    
                        writer = new OutputStreamWriter(dos);//, StandardCharsets.UTF_8)
                        writer.write(jsonObject.toString());
                        System.out.println("c");
                        writer.flush();
                        dos.flush();
    
                        System.out.println("output buffer size:" + dos.size());
                        char c = (char) dis.read();
                        while (c != '\0') {
                            System.out.print(c);
                            str = str.append(c);
    
                            if (dis.available() != 0) {
                                c = (char) dis.read();
                            } else break;
                        }
    
                        dos.flush();
                        System.out.println("String:" + str.toString());
                        normalLoginResponse = str.toString();
    
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    

    【讨论】:

      猜你喜欢
      • 2019-01-28
      • 2016-09-26
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多