2017-04-04 79 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之類的東西。