英文:
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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论