维持在一个AsyncTask的TCP连接AsyncTask、TCP

由网友(揽你到怀里)分享简介:我使用的AsyncTask建立一个TCP连接并发送/通过它接收数据。我目前的code看起来像这样的时刻: 公共类NetworkTask扩展的AsyncTask<无效,字节[],布尔> {    插座nsocket; //网络套接字    InputStream的NIS; //网络输入流    号的Outpu...

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

我目前的code看起来像这样的时刻:

 公共类NetworkTask扩展的AsyncTask<无效,字节[],布尔> {    插座nsocket; //网络套接字    InputStream的NIS; //网络输入流    号的OutputStream; //网络输出流    布尔bSocketStarted = FALSE;    字节[]缓冲区=新的字节[4096];    @覆盖    在preExecute保护无效(){        Log.i(TAG,关于preExecute);    }    @覆盖    保护布尔doInBackground(虚空...... PARAMS){//这运行在不同的线程        布尔结果= FALSE;        尝试{            //连接到地址            Log.i(TAG,doInBackground:创建套接字);            SocketAddress的SOCKADDR =新的InetSocketAddress(google.de,80);            nsocket =新的Socket();            nsocket.connect(套接字地址,5000); // 10第二个连接超时            如果(nsocket.isConnected()){                bSocketStarted = TRUE;                NIS = nsocket.getInputStream();                号= nsocket.getOutputStream();                Log.i(AsyncTask的,doInBackground:创建,溪流分配插座);                Log.i(AsyncTask的,doInBackground:等待inital数据......);                INT读= nis.read(缓冲,0,4096); //这是堵                而(bSocketStarted){                    如果(读大于0){                        字节[] = TempData的新的字节[阅读]                        System.arraycopy(缓冲,0,TempData的,0,读);                        publishProgress(TempData的);                        Log.i(TAG,doInBackground:得到了一些数据);                    }                }            }        }赶上(IOException异常五){            e.printStackTrace();            Log.i(TAG,doInBackground:IOException异常);            结果=真;        }赶上(例外五){            e.printStackTrace();            Log.i(TAG,doInBackground:异常);            结果=真;        } {最后            尝试{                nis.close();                nos.close();                nsocket.close();            }赶上(IOException异常五){                e.printStackTrace();            }赶上(例外五){                e.printStackTrace();            }            Log.i(TAG,doInBackground:成品);        }        返回结果;    }    公共布尔SendDataToNetwork(最后一个字节[] CMD){//你从主线程运行此。        //等到插座是开放的,并准备使用        waitForSocketToConnect();        如果(nsocket.isConnected()){            Log.i(TAG,SendDataToNetwork:收到书面消息,插座);            新主题(新的Runnable接口(){                公共无效的run(){                    尝试{                        nos.write(CMD);                    }                    赶上(例外五){                        e.printStackTrace();                        Log.i(TAG,SendDataToNetwork:短信发送失败捕获的异常。);                    }                }            }                    )。开始();            返回true;        }        其他            Log.i(TAG,SendDataToNetwork:不能发送消息关闭套接字。);        返回false;    }    公共布尔waitForSocketToConnect(){        //立即返回,当套接字已打开        如果(bSocketStarted)            返回true;        //等到插座是开放的,并准备使用        诠释计数= 0;        而(bSocketStarted&安培;!&安培; COUNT< 10000){            尝试{                视频下载(500);            }            赶上(InterruptedException的E)            {                e.printStackTrace();            }            数+ = 500;        }        返回bSocketStarted;    }    @覆盖    保护无效onProgressUpdate(字节[] ...值){        尝试{            如果(values​​.length大于0){                Log.i(TAG,onProgressUpdate:+值[0]。长度+接收字节数。);                字符串str =新的String(缓冲区,UTF8);                Log.i(TAG,STR);                tv.setText(STR);                tv.setMovementMethod(新ScrollingMovementMethod());            }        }赶上(例外五){            e.printStackTrace();        }        最后{}    }    @覆盖    保护无效onCancelled(){        Log.i(TAG,取消);    }    @覆盖    保护无效onPostExecute(布尔结果){        如果(结果){            Log.i(TAG,onPostExecute:已完成与错误。);        }其他{            Log.i(TAG,onPostExecute:已完成。);        }    }} 

我可以实例化的任务,并从我的活动叫 SendDataToNetwork 。然而,所有的文字我传给SendDataToNetwork,例如,GET / HTTP / 1.1不断将发送到服务器。

如何修改我的code保持 doInBackground 连接,什么也不做,直到我称之为 SendDataToNetwork 和发送字节到服务器后,只是等待,直到新的数据准备发送?基本上我想要运行的AsyncTask的,直到我明确取消(=关闭连接)吧。

解决方案

  nsocket.connect(SOCKADDR,5000); // 10第二个连接超时如果(nsocket.isConnected()){ 

测试是没有意义的。如果套接字未连接,连接()会抛出异常。

AsyncTask的原理

您读取循环也是根本性的缺陷,因为它不请继续阅读。有标准的解决方案如何读取一个流,例如:

 ,而((数= in.read(缓冲))0){  out.write(缓冲,0,计数);} 

waitForSocketToConnect()方法并没有真正做任何有用的事情无论是。

您需要重新考虑这一切。

I'm using an AsyncTask to establish a TCP Connection and sending/receiving data through it.

My current Code looks like this at the moment:

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.");
        }
    }
}

I can instantiate the Task and call SendDataToNetwork from my activity. However, all the text I pass to SendDataToNetwork, for example, 'GET / HTTP/1.1' is continously sent to the server.

How can I modify my Code to maintain the connection in doInBackground and do nothing until I call SendDataToNetwork and after sending bytes to the server just wait until new data is ready to be sent? Basically I want to run the AsyncTask until I explicitly cancel (= close the connection) it.

解决方案

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

The test is pointless. If the socket wasn't connected, connect() would have thrown an exception.

Your read loop is also fundamentally flawed, in that it doesn't keep reading. There are standard solutions as to how to read a stream, e.g.:

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

Your waitForSocketToConnect() method doesn't really do anything useful either.

You need to rethink all this.

阅读全文

相关推荐

最新文章