gpt4 book ai didi

java - 在 AsyncTask 中维护 TCP 连接

转载 作者:行者123 更新时间:2023-12-02 00:27:42 26 4
gpt4 key购买 nike

我使用 AsyncTask 建立 TCP 连接并通过它发送/接收数据。

我当前的代码现在看起来像这样:

public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
Socket nsocket; //Network Socket
InputStream nis; //Network Input Stream
OutputStream nos; //Network Output Stream
boolean bSocketStarted = false;
byte[] buffer = new byte[4096];

@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}

@Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
// Connect to address
Log.i(TAG, "doInBackground: Creating socket");
SocketAddress sockaddr = new InetSocketAddress("google.de", 80);
nsocket = new Socket();
nsocket.connect(sockaddr, 5000); //10 second connection timeout
if (nsocket.isConnected()) {
bSocketStarted = true;
nis = nsocket.getInputStream();
nos = nsocket.getOutputStream();
Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
int read = nis.read(buffer, 0, 4096); //This is blocking
while(bSocketStarted) {
if (read > 0){
byte[] tempdata = new byte[read];
System.arraycopy(buffer, 0, tempdata, 0, read);
publishProgress(tempdata);
Log.i(TAG, "doInBackground: Got some data");
}
}
}
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "doInBackground: IOException");
result = true;
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "doInBackground: Exception");
result = true;
} finally {
try {
nis.close();
nos.close();
nsocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, "doInBackground: Finished");
}
return result;
}

public boolean SendDataToNetwork(final byte[] cmd) { //You run this from the main thread.
// Wait until socket is open and ready to use
waitForSocketToConnect();

if (nsocket.isConnected()) {
Log.i(TAG, "SendDataToNetwork: Writing received message to socket");
new Thread(new Runnable() {
public void run() {
try {
nos.write(cmd);
}
catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "SendDataToNetwork: Message send failed. Caught an exception");
}
}
}
).start();
return true;
}
else
Log.i(TAG, "SendDataToNetwork: Cannot send message. Socket is closed");

return false;
}

public boolean waitForSocketToConnect() {
// immediately return if socket is already open
if (bSocketStarted)
return true;

// Wait until socket is open and ready to use
int count = 0;
while (!bSocketStarted && count < 10000) {
try {
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
count += 500;
}

return bSocketStarted;
}

@Override
protected void onProgressUpdate(byte[]... values) {
try {
if (values.length > 0) {
Log.i(TAG, "onProgressUpdate: " + values[0].length + " bytes received.");

String str = new String(buffer, "UTF8");
Log.i(TAG,str);
tv.setText(str);
tv.setMovementMethod(new ScrollingMovementMethod());
}
} catch (Exception e) {
e.printStackTrace();
}
finally {}
}
@Override
protected void onCancelled() {
Log.i(TAG, "Cancelled.");
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
Log.i(TAG, "onPostExecute: Completed with an Error.");

} else {
Log.i(TAG, "onPostExecute: Completed.");
}
}
}

我可以实例化任务并从我的 Activity 中调用 SendDataToNetwork。但是,我传递给 SendDataToNetwork 的所有文本(例如“GET/HTTP/1.1”)都会持续发送到服务器。

如何修改我的代码以维持 doInBackground 中的连接,并且在调用 SendDataToNetwork 之前不执行任何操作,并且在向服务器发送字节后只需等待新数据准备就绪将被寄出?基本上我想运行 AsyncTask 直到我明确取消(=关闭连接)它。

最佳答案

nsocket.connect(sockaddr, 5000); //10 second connection timeout
if (nsocket.isConnected()) {

测试毫无意义。如果套接字未连接,connect() 将引发异常。

您的读取循环也存在根本性缺陷,因为它不会继续读取。关于如何读取流有标准的解决方案,例如:

while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}

您的 waitForSocketToConnect() 方法也没有真正执行任何有用的操作。

你需要重新考虑这一切。

关于java - 在 AsyncTask 中维护 TCP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9681528/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com