从Android客户端向Python服务器发送字符串时的额外字符

时间:2014-07-24 22:36:01

标签: android python string sockets tcp

我通过TCP套接字从Android设备向python服务器发送一个字符串,但是当消息到达服务器时,前面有额外的字符。例如,如果我发送字符串

asdf

服务器上的结果是

\x00\x13asdf

任何人都知道为什么这些字符被添加到字符串的前面?有没有办法避免这种情况,或者我应该在服务器端剪掉这些?

反过来,服务器发送

fdsa

Android客户端收到

Nullfdsa

客户端代码(用Android,Java编写):

public static class PlaceholderFragment extends Fragment {

        TextView recieve;
        EditText addressText, portText, messageText;
        Button send, test;

        Socket socket = null;

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(
                    R.layout.fragment_customize_gateway, container, false);

            recieve = (TextView) rootView.findViewById(R.id.textView1);
            addressText = (EditText) rootView.findViewById(R.id.editText1);
            portText = (EditText) rootView.findViewById(R.id.editText2);
            messageText = (EditText) rootView.findViewById(R.id.editText3);

            send = (Button) rootView.findViewById(R.id.send);
            send.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    AsyncTCPSend tcpSend= new AsyncTCPSend(addressText.getText().toString(),Integer.parseInt(portText.getText().toString()), messageText.getText().toString());
                    tcpSend.execute();
                }
            });
            return rootView;
        }

public class AsyncTCPSend extends AsyncTask<Void, Void, Void> {
            String address;
            int port;
            String message;
            String response;
            AsyncTCPSend(String addr, int p, String mes) {
                address = addr;
                port = p;
                message = mes;
            }

            @Override
            protected Void doInBackground(Void... params) {
                Socket socket = null;
                try {
                    socket = new Socket("127.0.0.1", 4999);
                    DataOutputStream writeOut = new DataOutputStream(socket.getOutputStream());
                    writeOut.writeUTF(message);
                    writeOut.flush();

                    ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream(1024);
                    byte[] buffer = new byte[1024];

                    int bytesRead;
                    InputStream writeIn = socket.getInputStream();

                    while((bytesRead = writeIn.read(buffer)) != -1) {
                        writeBuffer.write(buffer,0,bytesRead);
                        response += writeBuffer.toString("UTF-8");
                    }
                    response = response.substring(4);   //Server sends extra "Null" string in front of data. This cuts it out
                } catch (UnknownHostException e){
                    e.printStackTrace();
                    response = "Unknown HostException: " + e.toString();
                    System.out.println(response);
                } catch (IOException e) {
                    response = "IOException: " + e.toString();
                    System.out.println(response);
                } finally {
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                recieve.setText(response);
                super.onPostExecute(result);
            }
        }

服务器代码(在Python中):

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        #Connect to database
        try:
            from pymongo import MongoClient
            dbclient = MongoClient()
            db = dbclient.WDI_database
            print("Database Connected")
        except pymongo.errors.ConnectionFailure as e:
            print("Database Failed: {}".format(e))

        col = db.users

        data2 = str(self.request.recv(1024), 'utf-8')
        print("Server: {}".format(data2));
        data = data2.split("||")
        try:
            #[2:] because we get two extra symbols in front of the username from Android
            username = data[0][2:] 
        except IndexError:
            username = ""
        try:
            password = data[1]
        except IndexError:
            password = ""
        try:
            camunits = data[2]
        except IndexError:
            camunits = 0
        try:
            homunits = data[3]
        except IndexError:
            homunits = 0
        post = {"user": username,
                "pass": password,
                "cam": camunits,
                "disp": homunits}
        col.insert(post)
        print(col.count())

        response = bytes("Received data for: {}".format(username), 'utf-8')
        self.request.sendall(response)

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    HOST, PORT = "", 5000

    tcpserver = ThreadedTCPServer((HOST, PORT-1), ThreadedTCPRequestHandler)
    server_thread = threading.Thread(target=tcpserver.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    print("TCP serving at port", PORT-1)

    while True:
        pass
    tcpserver.shutdown()

2 个答案:

答案 0 :(得分:1)

我想我对额外的角色有一些解释。

在java代码中,你没有得到额外的&#34; Null&#34;从套接字,response字符串变量未初始化,默认情况下它是null,你说

response += writeBuffer.toString("UTF-8");

所以你附加一些东西到一个空字符串,恰好是"null" + something

我会在声明中或在while循环之前初始化变量:

String response = "";

在Phyton代码中,我没有看到任何错误,因此我建议您编写发送到日志的内容,并查看额外字符是否在您发送的字节中。

而不是writeOut.writeUTF(message);

尝试socket.getOutputStream().write(message.getBytes()); // UTF-8是默认值。

并将其写入日志:

android.util.Log.w("SENT", String.format("[%s] %d", message, message.length()));

查看日志,了解您真正发送的内容。

答案 1 :(得分:0)

让java发送额外的字符。它也是我的情况。 我用过 -

data2 = data.strip()

如果data2 ==“(您想要的数据)”

//执行指令

等等。