从Android客户端向Python服务器发送字符串时多余字符问题

0 投票
2 回答
1614 浏览
提问于 2025-04-18 14:41

我正在通过TCP套接字从安卓设备发送一个字符串到一个Python服务器,但当消息到达服务器时,字符串前面多了一些额外的字符。例如,如果我发送的字符串是

asdf

那么在服务器上显示的结果会是

\x00\x13asdf

有人知道为什么这些字符会出现在字符串前面吗?有没有办法避免这种情况,还是说我应该在服务器端把这些字符去掉?

反过来,服务器发送

fdsa

安卓客户端接收到的是

Nullfdsa

客户端代码(用安卓,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

让Java发送多余的字符。在我的情况下也是这样。

我使用了 -

data2 = data.strip()

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

//执行指令

然后继续。

1

我觉得我可以解释一下那些多余字符的原因。

在Java代码中,你并不是从socket里得到一个额外的“Null”,而是response这个字符串变量没有被初始化,默认情况下它是null。你写了

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

,所以你是在一个null字符串上追加内容,这样就变成了"null" + 某些内容

我建议你在声明变量的时候或者在while循环之前初始化这个变量:

String response = "";

在Python代码中,我没有看到什么问题,因此我建议你把发送的内容记录到日志里,看看你发送的字节里是否有多余的字符。

可以把

writeOut.writeUTF(message);

改成

socket.getOutputStream().write(message.getBytes());

// UTF-8是默认编码。

然后把它写入日志:

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

查看日志,看看你到底发送了什么。

撰写回答