2013-08-05 206 views
3

我正在嘗試與服務器進行通信。但我似乎無法得到它從我的手機上的服務器的響應。它只是在無限循環中掛起。它在python客戶端中接收,但不在java中。有什麼我做錯了嗎?未從服務器接收Android套接字客戶端

服務器:

""" 
TODO: 
Save password to file 
Add password change feature 
some sort of garage open/close sensor? 
""" 
#import RPi.GPIO as GPIO 
import SocketServer 
import time 

#GPIO.setmode(GPIO.BOARD) 
#GPIO.setup(12,GPIO.OUT) 
auth = ""#Syntax: password-port 
#auth = "o-1234" #Debug 
global isOpen 
class TCPConnectionHandler(SocketServer.BaseRequestHandler): 
    """ 
    The RequestHandler class for our server. 

    It is instantiated once per connection to the server, and must 
    override the handle() method to implement communication to the 
    client. 
    """ 
    global isOpen #global is kinda like public in java 


    def handle(self): 
     isOpen = False 
     while 1: 
      self.data = self.request.recv(1024).strip() 
      print self.data 
      if self.data == '':#client ended stream 
       break 
      elif (self.data == auth.split('-')[0]):#if self.data matches the password 
       isOpen = (not isOpen)#change garage status 
       print isOpen 
       self.request.sendall('got_it')#dont leave the client hanging, let it know whats up 
#    GPIO.output(12,1) 
#    time.sleep(0.5)#simulate button press 
#    GPIO.output(12,0) 
      elif (self.data == 'req_state'):#sends back the current state of the garage 
       print isOpen 
       self.request.sendall(str(isOpen)) 

      else: 
       print 'wat?' 
       self.request.sendall('wat') 
     self.request.close()  

class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    # Ctrl-C will cleanly kill all spawned threads 
    daemon_threads = True 
    # much faster rebinding 
    allow_reuse_address = True 

    def __init__(self, server_address, RequestHandlerClass): 
     SocketServer.TCPServer.__init__(\ 
     self,\ 
     server_address,\ 
     RequestHandlerClass) 

if __name__ == "__main__": 

    HOST, PORT = "", int(auth.split('-')[1])#blank means localhost 
    print "Server started on " + HOST + ":"+ str(PORT) 
    server = Server((HOST, PORT), TCPConnectionHandler) 

    # Activate the server; this will keep running until you 
    # interrupt the program with Ctrl-C 
    server.serve_forever() 

Android客戶端:

package com.Civilizedgravy.madgarage; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.ObjectInputStream; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.Socket; 

import android.content.SharedPreferences; 
import android.os.AsyncTask; 
import android.preference.PreferenceManager; 
import android.util.Log; 

public class Socketstuff extends AsyncTask<String, String, String> { 

    @Override 
    protected void onProgressUpdate(String... values) { 
     // TODO Auto-generated method stub 
     super.onProgressUpdate(values); 
     ma.dbg.setText(values[0]); 
    } 

    public boolean connected; 
    private final int PORT = 1234; 
    private String HOMEIP = "0.0.0.0"; 
    private String pass; 
    public MainActivity ma; 

    public Socketstuff(MainActivity ma) { 
     this.ma = ma; 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     publishProgress(""); 
     SharedPreferences sharedPref = PreferenceManager 
       .getDefaultSharedPreferences(ma); 
     HOMEIP = sharedPref.getString("pref_ip", "0.0.0.0"); 
     pass = sharedPref.getString("pref_Passkey", "o-1234"); 
     // TODO Auto-generated 
     Log.d("MadG", 
       HOMEIP + ", " + pass + ", " 
         + String.valueOf(pass.split("-").length)); 
     if (pass.split("-").length <= 2) { 

      try { 
       InetAddress serverAddr = InetAddress.getByName(HOMEIP); 
       Log.d("ClientActivity", "C: Connecting..."); 
       Socket socket = new Socket(serverAddr, Integer.parseInt(pass 
         .split("-")[1])); 

       try { 
        Log.d("ClientActivity", "C: Sending command."); 
        PrintWriter out = new PrintWriter(new BufferedWriter(
          new OutputStreamWriter(socket.getOutputStream())), 
          true); 
        if (params[0].equals("o")) { 
         out.println(pass.split("-")[0]); 
         Log.d("MadG", "Open"); 
        } else { 
         Log.d("ClientActivity", "Requesting state."); 
         out.println("req_state"); 
         Log.d("MadG", "Waiting for response..."); 
         String resp = StreamToString(socket.getInputStream());//hangs here 
         Log.d("MadG", "Got response:" + resp); 
         publishProgress(resp); 

        } 

        Log.d("ClientActivity", "C: Sent."); 

        out.println("\n"); 
       } catch (Exception e) { 
        publishProgress("ERROR: unable to send command"); 
        Log.e("ClientActivity", "S: Error", e); 
       } 
       socket.close(); 
       Log.d("ClientActivity", "C: Closed."); 
      } catch (Exception e) { 
       publishProgress("ERROR: unable to connect"); 
       Log.e("ClientActivity", "C: Error", e); 
       connected = false; 
      } 
     } 
     return HOMEIP; 

    } 
    public static String StreamToString(InputStream is) throws Exception { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 

     while ((line = reader.readLine()) != null) { 
      Log.d("MadG", sb.toString()); 
      sb.append(line); 
     } 

     is.close(); 

     return sb.toString(); 
    } 
} 
+0

它前懸掛年底或在日誌消息之後,你得到了迴應? –

+0

@JoeMinichino它掛起之前,我的意思是說它掛在字符串resp .. –

回答

1

我發現了這個問題。這是掛的原因是的readLine()在等待被如此收到了「\ n」字符我改變了服務器發送「\ n」在響應

self.request.sendall('wat' + '\n') 
1

有沒有在最後一行被送到一回?如果不是readLine()將掛起,直到發送返回。另外,如果您使用的是HTTP 1.1,則連接可能會保持打開並等待響應。確保你的內容長度標題也是正確的。

+0

是的,它應該返回字符串「真」或「假」。我正在使用TCP套接字連接而不是HTTP –

+0

它返回字符串「true」還是字符串「true \ n」?因爲如果沒有\ n那麼readLine將永遠不會完成。 –

+0

修正了它,直到我發佈答案後才注意到這個評論 –

相關問題