【问题标题】:Extra characters when sending String from Android client to Python Server将字符串从 Android 客户端发送到 Python 服务器时出现额外字符
【发布时间】:2014-09-16 16:24:23
【问题描述】:

我正在通过 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()

【问题讨论】:

  • TCP 是一个流,你在一侧发送的内容在另一端收到,不多不少。输入相关代码(发送和接收),以便我们帮助您检测问题所在。
  • 如果您想在帖子中添加更多代码或信息,请告诉我。

标签: android python string sockets tcp


【解决方案1】:

我想我对多余的字符有了一些解释。

在java代码中,你没有从socket中得到一个额外的“Null”,response字符串变量没有初始化,默认为null,你说

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

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

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

String response = "";

在 Phyton 代码中,我没有发现任何问题,因此我建议您将发送到 Log 的内容写下来,看看额外的字符是否在您发送的字节中。

而不是writeOut.writeUTF(message);

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

并将其写入日志:

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

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

【讨论】:

  • 我将 writeOut.writeUTF(message) 更改为您建议的内容,并且不再收到多余的字符。似乎 writeOut 部分中的某处导致将额外字符添加到字符串中。
【解决方案2】:

让 java 发送额外的字符。在我的情况下也是如此。 我用过 -

data2 = data.strip()

如果 data2 == "(你想要的数据)"

//执行指令

等等。

【讨论】:

    猜你喜欢
    • 2016-09-11
    • 2013-04-28
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    相关资源
    最近更新 更多