2017-04-04 29 views
9

我无法获得套接字连接的响应,我不明白代码有什么问题。 我可以能够建立使用IP地址和端口号的套接字连接,它是进入没有在套接字连接中得到响应

if (nsocket.isConnected()) {} 

当我通过telnet试过我能得到响应。但输入有一些其它参数,如:

POST /的setMap HTTP/1.1 主机:192.168.1.1 内容类型:应用/ JSON;字符集= UTF-8 内容长度:1234

{ “CMD”: “request_get_file_list”, “验证”: “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; 
} 

请帮我找到问题。我很困难。请帮我解决问题

+0

可能是你可以尝试“抓包”的应用程序,看看是否有任何响应,你无法看到或收到您的应用程序内的,但实际上,你收到您的设备 –

+1

输入是一个POST?如果您正在实施HTTP,则在开始之前需要熟悉RFC 2616。太宽泛。 NB'Socket.isConnected()'在你测试的时候不可能是假的。不要写无意义的代码。 – EJP

+1

@EJB对不起,我是socket连接的新手。那么我该怎么做才能解决这个问题? – Liya

回答

0

非常感谢您的每一个答案。所有回答都会引导我选择正确的答案。我可以解决这个问题,这里是代码。

   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(); 
       } 
4

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

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

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

编辑

在你给出的例子中,你都可以从服务器的响应,你应该使用HttpURLConnection,你并不需要实现插座。只需GETPOST即可使用HttpURLConnection获取或推送您的数据。

4

对于Android中的套接字连接,您可以使用简单实现套接字连接的this gist file

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); 
     } 
    } 

UPDATE

如果你想要设置自定义标题,就应该把它们写到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"); 
+1

超出范围,@Liya询问如何添加标题和套接字,而不是什么你回答。 –

+1

@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之类的东西。