在Android Studio中使用套接字时出现异常
我刚刚启动我的第一个Android应用程序,在Android Studio中使用套接字时遇到问题 我正试图屏蔽与服务器的连接。我使用异步任务来实现这一点。当我启动应用程序时,创建了套接字get,发送第一个包工作正常。但是当我尝试发送另一个包时,它抛出一个异常,表示套接字已关闭 我尝试了很多方法,比如在发送第二个包之前检查套接字是否已连接,如果未连接,则创建一个新的套接字。Android Studio中的调试向我显示,套接字“nsocket”从未关闭。下面是我调试代码的截图: 以下是我的异步任务代码:在Android Studio中使用套接字时出现异常,android,sockets,exception,android-studio,android-asynctask,Android,Sockets,Exception,Android Studio,Android Asynctask,我刚刚启动我的第一个Android应用程序,在Android Studio中使用套接字时遇到问题 我正试图屏蔽与服务器的连接。我使用异步任务来实现这一点。当我启动应用程序时,创建了套接字get,发送第一个包工作正常。但是当我尝试发送另一个包时,它抛出一个异常,表示套接字已关闭 我尝试了很多方法,比如在发送第二个包之前检查套接字是否已连接,如果未连接,则创建一个新的套接字。Android Studio中的调试向我显示,套接字“nsocket”从未关闭。下面是我调试代码的截图: 以下是我的异步任务代
public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
private boolean finished = false;
private boolean socket = false;
private boolean messageSuccess = false;
Socket nsocket; //Network Socket
InputStream nis; //Network Input Stream
OutputStream nos; //Network Output Stream
SocketAddress sockaddr;
Client c = new Client();
Context context = getApplicationContext();
@Override
protected void onPreExecute() {
Log.i("AsyncTask", "onPreExecute");
}
@Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
socket = false;
try {
Log.i("AsyncTask", "doInBackground: Creating socket");
sockaddr = new InetSocketAddress(SERVERHOST, SERVERPORT);
nsocket = new Socket();
nsocket.connect(sockaddr, 10000); //10 second connection timeout
socket = true;
while (finished) {
finished = false;
if (nsocket.isConnected()) {
Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
}
else {
}
}
} catch (IOException e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: IOException");
socket = false;
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
socket = false;
}
return socket;
}
public boolean closeSocket() {
try {
//nis.close();
nos.close();
nsocket.close();
Log.i("AsyncTask", "closeSocket: Finished");
socket = false;
return true;
} catch (IOException e) {
Log.i("AsyncTask", "closeSocket: IO Failed");
e.printStackTrace();
return false;
} catch (NullPointerException e) {
Log.i("AsyncTask", "closeSocket: Socket or output Stream already closed.");
e.printStackTrace();
socket = false;
return false;
}catch (Exception e) {
Log.i("AsyncTask", "closeSocket: Failed");
e.printStackTrace();
return false;
}
}
public boolean SendDataToNetwork(final String cmd) { //You run this from the main thread.
if (!nsocket.isClosed()) {
Log.i("AsyncTask", getString(R.string.StatusSendAlarm));
Log.i("AsyncTask", cmd);
messageSuccess = false;
publishProgress("1".getBytes());
try {
new Thread(new Runnable() {
public void run() {
try {
nos = nsocket.getOutputStream();
nos.write(cmd.getBytes());
nos.flush();
nos.close();
finished = true;
messageSuccess = true;
}catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "SendDataToNetwork: Message send failed. Caught an exception");
publishProgress("2".getBytes());
}
}
}).start();
} catch (Exception e) {
Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception");
publishProgress("3".getBytes());
}
}
Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Socket closed");
return messageSuccess;
}
@Override
protected void onProgressUpdate(byte[]... values) {
if (values.length > 0) {
if (values[0].equals("1")){
Log.i("AsyncTask", "onProgressUpdate: " + values[0].length + " bytes received.");
c.toastmessage(context, getString(R.string.StatusSendAlarm), Toast.LENGTH_SHORT);
}
else if (values[0].equals("2")) {
Log.i("AsyncTask", "onProgressUpdate2: " + values[0].length + " bytes received.");
c.toastmessage(context, getString(R.string.StatusSendAlarmFail)+" 2", Toast.LENGTH_SHORT);
}
else if (values[0].equals("3")) {
Log.i("AsyncTask", "onProgressUpdate3: " + values[0].length + " bytes received.");
c.toastmessage(context, getString(R.string.StatusSendAlarmFail)+" 3", Toast.LENGTH_SHORT);
}
//textStatus.setText(new String(values[0]));
}
}
@Override
protected void onCancelled() {
Log.i("AsyncTask", "Cancelled.");
}
@Override
protected void onPostExecute(Boolean result) {
if (socket) {
Log.d("AsyncTask", getString(R.string.socket_success));
if (nos != null) {
if (messageSuccess) {
c.toastmessage(context, getString(R.string.alarm_success),Toast.LENGTH_LONG);
mCheckBox.toggle();
}
else {
c.toastmessage(context, getString(R.string.alarm_fail),Toast.LENGTH_LONG);
mCheckBox.toggle();
}
}
}
else {
Log.d("AsyncTask", getString(R.string.socket_fail));
}
}
}
您自己正在关闭流,从而关闭套接字
nos = nsocket.getOutputStream();
你应该只做一次。并非每一条信息都如此
您自己正在关闭流,从而关闭套接字
nos = nsocket.getOutputStream();
你应该只做一次。并非每封邮件都如此。我找到了解决问题的方法。我采纳了你的建议(连接、发送、阅读一个任务)并实施了它。现在调用异步任务,当我按下按钮,它将字符串传递给doInBackground函数。在那里,我创建套接字连接,打开OutputStream并发送消息。之后,我关闭所有连接 我必须继续使用“nos.close()”,因为发送“\n”或“\n\n”无效 异步任务调用
private OnClickListener btnSendListener = new OnClickListener() {
public void onClick(View v) {
EditText at = (EditText) findViewById(R.id.alarmText);
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
String atext = at.getText().toString();
if (atext.length() > 0) {
String alarmtext =
"<event>\n" +
"<address>" + EINHEIT + "</address>\n" +
"<timestamp>" + ts + "</timestamp>\n" +
"<message>" + atext + "</message>\n" +
"</event>";
networktask = new NetworkTask(); //New instance of NetworkTask
networktask.execute(alarmtext);
}
else {
toastmessage(context, getString(R.string.noText), Toast.LENGTH_LONG);
}
}
};
感谢greenapps的帮助我找到了解决问题的方法。我采纳了你的建议(连接、发送、阅读一个任务)并实施了它。现在调用异步任务,当我按下按钮,它将字符串传递给doInBackground函数。在那里,我创建套接字连接,打开OutputStream并发送消息。之后,我关闭所有连接 我必须继续使用“nos.close()”,因为发送“\n”或“\n\n”无效 异步任务调用
private OnClickListener btnSendListener = new OnClickListener() {
public void onClick(View v) {
EditText at = (EditText) findViewById(R.id.alarmText);
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
String atext = at.getText().toString();
if (atext.length() > 0) {
String alarmtext =
"<event>\n" +
"<address>" + EINHEIT + "</address>\n" +
"<timestamp>" + ts + "</timestamp>\n" +
"<message>" + atext + "</message>\n" +
"</event>";
networktask = new NetworkTask(); //New instance of NetworkTask
networktask.execute(alarmtext);
}
else {
toastmessage(context, getString(R.string.noText), Toast.LENGTH_LONG);
}
}
};
感谢greenapps的帮助可能服务器在收到第一条消息后关闭了连接。'public boolean SendDataToNetwork(final String cmd){//您从主线程运行此函数。'.确实如此。因此,请从AsyncTask类中删除此函数,并将其放在活动中。然后显示第一次和第二次调用此函数的时间和方式。当我按下UI上的按钮时,会调用此函数。我在上面添加了代码。您为什么不对我的第一条注释进行注释?重复:“删除此函数。”“从您的AsyncTask类中删除连接,并将其放在您的活动中”。可能服务器在收到第一条消息后关闭了连接。“public boolean SendDataToNetwork(final String cmd)”{//您从主线程运行此函数。'.确实如此。因此,请从AsyncTask类中删除此函数,并将其放在活动中。然后显示第一次和第二次调用此函数的时间和方式。当我按下UI上的按钮时,会调用此函数。我在上面添加了代码。您为什么不对我的第一条注释进行注释?重复:“删除此函数。”从AsyncTask类中删除,并将其放在“活动”中。不幸的是,当我不关闭输出流时,它不会发送消息。我按照您在开始时所说的方式收到了消息,并且在想为什么它不发送消息后,我关闭了输出流,并且成功了。好的。当发送者的
no.write(cmd.getBytes());
与接收器的read()
不匹配。接收器试图读取什么?一些字节?一行?我想你没有发送一行。我试图发送的文本是“\n”+EINHEIT+“\n”+ts+“\n”+atext+“\n”接收端是可以通过套接字连接接收此类字符串的第三方程序。请尝试在该端发送\n或两个。因此nos.write((cmd+“\n”).getBytes();
或nos.write((cmd+“\n\n”).getBytes())
您必须找出接收者希望消息结束的内容。询问制作接收者的人。您没有回答我的问题,接收者试图阅读的内容。不幸的是,当我没有关闭输出流时,它没有发送消息。我按照您在开始时所说的方式收到了消息,在想知道为什么它没有发送消息后,我将其删除osed输出流并正常工作。好的。当发送方的nos.write(cmd.getBytes());
与接收方的read()不匹配时,经常会发生这种情况。接收方试图读取什么?一些字节?一行?我想您没有发送一行。我试图发送的文本是“\n”+EINHEIT+“\n”+ts+“\n”+atext+“\n”接收端是可以通过套接字连接接收此类字符串的第三方程序。请尝试在该端发送\n或两个。因此nos.write((cmd+“\n”).getBytes();
或nos.write((cmd+“\n\n”).getBytes())
你必须找出接收者期望消息结束的内容。询问接收者。你没有回答我的问题,接收者试图阅读的内容。注意:如果你只在doInBackground中使用messageSuccess、sockaddr和nsocket(我想你是这样做的),然后在那里声明它们。进一步使用e.getMessage()要查看正确的message.Log.e(“AsyncTask”,“后台任务:IOException:+e.getMessage()”);请注意:如果您仅在doInBackground中使用messageSuccess、sockaddr和nsocket(我认为您是这样),请在那里声明它们。进一步使用e.getMessage()查看正确的message.Log.e(“AsyncTask”,“后台任务:IOException:+e.getMessage()));
private OnClickListener btnSendListener = new OnClickListener() {
public void onClick(View v) {
EditText at = (EditText) findViewById(R.id.alarmText);
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
String atext = at.getText().toString();
if (atext.length() > 0) {
String alarmtext =
"<event>\n" +
"<address>" + EINHEIT + "</address>\n" +
"<timestamp>" + ts + "</timestamp>\n" +
"<message>" + atext + "</message>\n" +
"</event>";
networktask = new NetworkTask(); //New instance of NetworkTask
networktask.execute(alarmtext);
}
else {
toastmessage(context, getString(R.string.noText), Toast.LENGTH_LONG);
}
}
};
protected Boolean doInBackground(String... params) { //This runs on a different thread
messageSuccess = false;
String alarmtext = params[0];
try {
Log.i("AsyncTask", "Background Task: Creating socket...");
sockaddr = new InetSocketAddress(SERVERHOST, SERVERPORT);
nsocket = new Socket();
nsocket.connect(sockaddr, 10000); //10 second connection timeout
Log.i("AsyncTask", "Background Task: Socket created");
nos = nsocket.getOutputStream();
nos.write(alarmtext.getBytes());
closeSocket();
messageSuccess = true;
} catch (IOException e) {
e.printStackTrace();
Log.e("AsyncTask", "Background Task: IOException");
Log.i("AsyncTask", getString(R.string.socket_fail));
messageSuccess = false;
} catch (Exception e) {
e.printStackTrace();
Log.e("AsyncTask", "Background Task: Exception");
Log.i("AsyncTask", getString(R.string.socket_fail));
messageSuccess = false;
}
return messageSuccess;
}