首页 > 解决方案 > Android Client Socket not sending nor recieving messages to external server

问题描述

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?

标签: javaandroidsocketsclient

解决方案


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


推荐阅读