Android客户端套接字未能发送或接收来自外部服务器的消息

huangapple go评论76阅读模式
英文:

Android Client Socket not sending nor recieving messages to external server

问题

我是Android的新手。我有一个客户端类,我的主要活动引用它。客户端类连接到一个外部设备,该设备充当服务器,但它从未发送我试图发送到服务器的消息。我知道这不是连接的问题,因为在创建套接字时,我将setKeepAlive()设置为true,当我尝试发送消息时没有抛出异常,socket.isConnected()返回true,如果我在发送消息之前尝试连接套接字,它会抛出“已连接”异常。我尝试了在我的字符串消息结尾处使用各种回车、换行和传输结束字符,我正在刷新我的dataoutputstream,并且我具有

权限。我没有收到任何错误消息,我只是在Wireshark中看不到请求被发送,我的代码如下:

public class Client {
    // 代码略
}

public class MainActivity extends AppCompatActivity {
    // 代码略
}

我查看了类似的问题,所有我看到的答案都建议你在消息的末尾使用换行、回车、传输结束字符,使用flush,或在清单中包含Internet权限,这些我都已经做了。我使用PrintWriter、DataOutputStream、BufferedWriter,我已将消息写成字节数组、二进制字符串、UTF和ASCII字符数组,但都没有成功,请有人告诉我我做错了什么吗?

英文:

I am new to Android. I I have a client class that my main activity references. The client class connects a client socket to an external device that functions as a server, however it never sends the message I'm trying to send over to the server. I know its not the connection because when creating the socket I set setKeepAlive() to true, no exception is thrown when I try to send the message, socket.isConnected() returned true and if I try to connect the socket right before sending the message it throws an "already connected" exception. I have tried ending my string message with all sorts of carriage, newline and end of transmission characters, I am flushing my dataoutpstream and I have the

<uses-permission android:name="android.permission.INTERNET" />

permission. I do not get any error messages, I just don't see the request being sent in Wireshark, My code is as follows:

public class Client {
private static final String TAG = "Client";
    private InputStream reader;
    private DataOutputStream writer;
    private Socket socket;
    private SocketAddress endpoint;
    private String sendMessage, recievedMessage, ip; // Request = iso8583.stISORequest;
    private int port, bytesRead = -1;
    private boolean messageSent = false,
            messageRecieved = false;
    ByteArrayOutputStream Bytearrayoutputstream;
    byte[] 	response1 = new byte[ 512 ],
            response2 = new byte[ 512 ];

public Client(String ip, int port) throws Exception {

        setIp(ip);
        setPort(port);
        setSocket();
        setIO();
    }

    private void setIp(String hostIp) throws Exception {

        Pattern ipPattern = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$");
        Matcher ipMatch = ipPattern.matcher(hostIp);

        if (!ipMatch.find()) {
            throw new Exception("invalid ip format");
        }

        else
            this.ip = hostIp;
    }

    private void setPort(int hostPort) throws Exception {

        Pattern portPattern = Pattern.compile("[0-9]{4}$"); // contains exactly 4 digits
        Matcher portMatch = portPattern.matcher(hostPort+"");

        if (!portMatch.find()) {
            throw new Exception("host port must be 4 digits from 0-9");
        }

        else
            this.port = hostPort;
    }

public void send() throws IOException {

        /* // connection test is not needed
        socket.connect(endpoint); // throws already connected exeption
        */

        this.messageRecieved = false; // toogle to false so transaction is not wrongfully assummed to have been recieved from pinpad

        byte [] request = this.sendMessage.getBytes(); //stRequest.getBytes();
        writer.write(request);
        writer.flush();

        this.messageSent = true;
    }

    public void recieveMessage() throws IOException, InterruptedException {

        this.messageSent = false; // toogle to false so the next transaction is not wrongfully assumed to have been sent to pinpad
        StringBuilder stringBuilder = new StringBuilder();

        while( ( bytesRead = reader.read( response1 ) ) != -1 )
        {
            Bytearrayoutputstream.write( response1, 0, bytesRead);
            stringBuilder.append(Bytearrayoutputstream);
        }

        if(bytesRead == -1){
            Log.i(TAG,"did not recieve");
            response1[0]	=	(byte)(0x20);
            response1[1]	=	(byte)(0x20);
        }

        int longitud	=	response1[1];
        response2		=	Arrays.copyOf(response1, longitud+2);
        Log.i(TAG, "Respuesta 1 SimHost: " +toHex(response2));

        this.recievedMessage = stringBuilder.toString();

        if(!(recievedMessage == null) || !recievedMessage.isEmpty())
            this.messageRecieved = true;
    }

private void setSocket() throws IOException {

        socket = new Socket();
        int timeout = 15000;
        endpoint = new InetSocketAddress(ip, port);
        socket.connect(endpoint, timeout);
        socket.setKeepAlive(true);

    }

    private  void setIO() {

        try {
            writer =  new DataOutputStream(socket.getOutputStream());
            Bytearrayoutputstream = new ByteArrayOutputStream();
            reader = socket.getInputStream();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

public class MainActivity extends AppCompatActivity {

Button btn;
EditText Ip, hPort;

String sHostIP = "",
        iHostPort = "",
        response = "";

Client client;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Ip = (EditText) findViewById(R.id.Ip);
    hPort = (EditText) findViewById(R.id.port);
    btn = (Button) findViewById(R.id.btn);

    btn.setOnClickListener(new View.OnClickListener() {
        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void onClick(View v) {

            try {

                sHostIP = Ip.getText().toString();
                iHostPort = hPort.getText().toString();
      
                }

                logon();

            } catch (Exception e) {

                showToast(e.getMessage());
            }
        }
    });
}

private void showToast(String message) {

    Toast toast = Toast.makeText(getApplicationContext(),
            message,
            Toast.LENGTH_SHORT);

    toast.show();
}


@RequiresApi(api = Build.VERSION_CODES.O)
private void logon() throws Exception {

    String message = "this is a message\n";

    Thread emulator = new Thread(() -> {

        try{
            client = new Client(sHostIP, Integer.parseInt(iHostPort));
            client.setSendMessage(message);
            client.send();

            Thread.sleep(32000);

            if (client.getSendStatus() == true) {

                try {
                    client.recieveMessage();
                    Thread.sleep(32000); 
                }

                catch (Exception e){
                    response = "exception happened could not send message";
                }

                if(client.getRecievedStatus() == true && !client.getRecievedMessage().isEmpty())
                    response = client.getRecievedMessage();

                else
                    response = "did not recieve a response";
            } // if

            else
                response = "message was not sent";

            client.closeAll(); // finalize
        }

        catch (Exception e){
            e.printStackTrace();
        }

        runOnUiThread(()->{

            showToast(response);

        }); // inner thread

    }); // outer thread

    emulator.start();

} // logon

} // class

I have looked at similar questions and all the answers I have seen recommend you end the message in in a newline, carriage, end of transmission character, use flush, or include the internet permission in the manifest which I'm already doing. I have used PrintWriter, DataOutputStream, BufferedWriter, I have written the message as bytes, binary string, UTF and ASCII characters array and nothing worked, can someone please enlighten me as to what I am doing wrong?

答案1

得分: 0

问题出在编码上。这行代码解决了它:this.sendMessage.getBytes(StandardCharsets.ISO_8859_1);

英文:

The problem was the encoding. This line of coded solved it this.sendMessage.getBytes(StandardCharsets.ISO_8859_1);

huangapple
  • 本文由 发表于 2020年10月24日 04:58:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/64507219.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定