的Android的AsyncTask不exectued - 尝试将消息发送到TCP服务器

问题描述 投票:0回答:1

目前我正在试图从我的Android系统的智能手机将消息发送到一个树莓派。我实现了一个Android客户端通过此处给出的示例代码:

Really simple TCP client

我改变了IP地址的端口,因此它与我的服务器上运行的PI工作。该服务器是用C语言编写,并切换到Android之前,我实现了一个C-Client,它至今工作没有任何问题。

服务器只需要接收消息,然后打印出它并停止,所以它是非常简单的。

编辑3

我创造了新的输出,用于调试和分析,我可以搞到现在的想法是什么是行不通的。据我所看到的,永远不会执行的SendMessageTask

服务器输出现在:

成功 - 创建套接字

成功 - 绑定

听力

成功 - 接受

现在它档,“读书......”从不打印! (应在while循环发生)

在Android中我收到以下neccessary输出:

d / TCP客户端:C:连接...

d / TcpOptimizer:TcpOptimizer-ON

- >连接发生

当我按下发送按钮:

d /化MyMessage1:按钮被推

d / myMessage:测试

但我没有得到应在SendMessageTask被记录的消息

当我点击断开按钮服务器打印:

客户端断开连接

而现在Android的日志:

d / RESPONSE FROM SERVER:S:收到的消息: '空'

d / sendMessageTask:尝试发送邮件

d / TcpClient的:不能发送 - > mBufferOut为null

因此,我的猜测是,该SendMessageTask从来没有运行,直到它失败,因为断开,但为什么呢?

编辑3 - 完

这是(编辑)服务器代码:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>


int main(){
    int welcomeSocket, newSocket, read_size;
    char buffer[10000];
    struct sockaddr_in serverAddr;
    struct sockaddr_storage serverStorage;
    socklen_t addr_size;

    /*---- Create the socket. The three arguments are: ----*/
    /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
    welcomeSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (welcomeSocket == -1)    {
        printf("Could not create socket\n");
    }else {
        printf("Success - create socket\n");
    }

    /*---- Configure settings of the server address struct ----*/
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(7891);
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    /* Set all bits of the padding field to 0 */
    memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

    /*---- Bind the address struct to the socket ----*/
    if(bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0){
        printf("Error - Binding\n");
    }else {
        printf("Success - Binding\n");
    }

    /*---- Listen on the socket, with 5 max connection requests queued ----*/
    if(listen(welcomeSocket,5)==0)
        printf("Listening\n");
    else
        printf("Error\n");

    /*---- Accept call creates a new socket for the incoming connection ----*/
    addr_size = sizeof serverStorage;
    newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
    if(newSocket < 0){
        printf("Error - Accept\n");
    }else {
        printf("Success - Accept\n");
    }

    while( (read_size = recv(newSocket, buffer, 10000, 0)) > 0){
        write(newSocket, buffer, strlen(buffer));
        printf("reading...");
    }

    if(read_size == 0){
        printf("Client disconnected");
        fflush(stdout);
    }
    else if(read_size == -1){
        printf("Error - recv failed");
    }
    return 0;
}

我不太清楚,如果参数

welcomeSocket = socket(AF_INET, SOCK_STREAM, 0);

仍然是正确的?

客户码在Android是:

import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClient {

    public static final String TAG = TcpClient.class.getSimpleName();
    public static final String SERVER_IP = "192.168.4.1"; //server IP address
    public static final int SERVER_PORT = 7891;
    // message to send to the server
    private String mServerMessage;
    // sends message received notifications
    private OnMessageReceived mMessageListener = null;
    // while this is true, the server will continue running
    private boolean mRun = false;
    // used to send messages
    private PrintWriter mBufferOut;
    // used to read messages from the server
    private BufferedReader mBufferIn;

    /**
     * Constructor of the class. OnMessagedReceived listens for the messages received from server
     */
    public TcpClient(OnMessageReceived listener) {
        mMessageListener = listener;
    }

    /**
     * Sends the message entered by client to the server
     *
     * @param message text entered by client
     */
    public void sendMessage(final String message) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if (mBufferOut != null) {
                    Log.d(TAG, "Sending: " + message);
                    mBufferOut.println(message);
                    mBufferOut.flush();
                }else{
                    Log.d(TAG, "Cannot send --> mBufferOut is null");
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    /**
     * Close the connection and release the members
     */
    public void stopClient() {

        mRun = false;

        if (mBufferOut != null) {
            mBufferOut.flush();
            mBufferOut.close();
        }

        mMessageListener = null;
        mBufferIn = null;
        mBufferOut = null;
        mServerMessage = null;
    }

    public void run() {

        mRun = true;

        try {
            //here you must put your computer's IP address.
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

            Log.d("TCP Client", "C: Connecting...");

            //create a socket to make the connection with the server
            Socket socket = new Socket(serverAddr, SERVER_PORT);

            try {

                //sends the message to the server
                mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);


                //receives the message which the server sends back
                mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));


                //in this while the client listens for the messages sent by the server
                while (mRun) {
                    /*
                    mServerMessage = mBufferIn.readLine();

                    if (mServerMessage != null && mMessageListener != null) {
                        //call the method messageReceived from MyActivity class
                        mMessageListener.messageReceived(mServerMessage);
                    }
*/
                }

                Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");

            } catch (Exception e) {
                Log.e("TCP", "S: Error", e);
            } finally {
                //the socket must be closed. It is not possible to reconnect to this socket
                // after it is closed, which means a new socket instance has to be created.
                socket.close();
            }

        } catch (Exception e) {
            Log.e("TCP", "C: Error", e);
        }

    }

    //Declare the interface. The method messageReceived(String message) will must be implemented in the Activity
    //class at on AsyncTask doInBackground
    public interface OnMessageReceived {
        public void messageReceived(String message);
    }

}

而我(编辑)Mainactivity包括的AsyncTask的连接

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Button;

public class MyActivity extends AppCompatActivity {

    private TextView mTextMessage;
    private TextView myAwesomeTextView;

    private TcpClient mTcpClient;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    mTextMessage.setText(R.string.title_home);
                    return true;
                case R.id.navigation_dashboard:
                    mTextMessage.setText(R.string.title_dashboard);
                    return true;
                case R.id.navigation_notifications:
                    mTextMessage.setText(R.string.title_notifications);
                    return true;
            }
            return false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_myActivity);

        mTextMessage = (TextView) findViewById(R.id.message);
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

        myAwesomeTextView = (TextView)findViewById(R.id.editText);

        //TCP connect
        new ConnectTask().execute("");

        //Buttons
        final Button button_Send = findViewById(R.id.button_Send);
        button_Send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                //Set text (debugging)
                myAwesomeTextView.setText("My Awesome Text");
                Log.d("myMessage1", "button pushed ");

                //sends the message to the server
               String message = "testing\0";
                //String message = "testing\n\r";

                if (mTcpClient != null) {
                    new SendMessageTask().execute(message);

                    //not needed just for debugging
                    Log.d("myMessage", "testing ");
                }

            }
        });

        final Button button_Disconnect = findViewById(R.id.button_Disconnect);
        button_Disconnect.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                if (mTcpClient != null) {
                    mTcpClient.stopClient();
                }

            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mTcpClient != null) {
            // disconnect
            new DisconnectTask().execute();
        }

    }

    /**
     * Sends a message using a background task to avoid doing long/network operations on the UI thread
     */
    public class SendMessageTask extends AsyncTask<String, Void, Void> {

        @Override
        protected Void doInBackground(String... params) {

            // send the message
            mTcpClient.sendMessage(params[0]);

            Log.d("sendMessageTask", "try to send message ");


            return null;
        }

        @Override
        protected void onPostExecute(Void nothing) {
            super.onPostExecute(nothing);

            //nothing to do yet
        }
    }

    /**
     * Disconnects using a background task to avoid doing long/network operations on the UI thread
     */
    public class DisconnectTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... voids) {

            // disconnect
            mTcpClient.stopClient();
            mTcpClient = null;

            return null;
        }

        @Override
        protected void onPostExecute(Void nothing) {
            super.onPostExecute(nothing);

            //nothing to do yet
        }
    }

    public class ConnectTask extends AsyncTask<String, String, TcpClient> {

        @Override
        protected TcpClient doInBackground(String... message) {

            //we create a TCPClient object and
            mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
                @Override
                //here the messageReceived method is implemented
                public void messageReceived(String message) {
                    //this method calls the onProgressUpdate
                    publishProgress(message);
                }
            });
            mTcpClient.run();

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);

            Log.d("test", "response " + values[0]);
            //process server response here....
        }
    }
}

编辑#2(失败的行为仍然存在)

  • 在的TcpClient的运行方法未注释的同时(mRun)环 - >想也许套接字通过最终已发送消息之前关闭。
  • 移动的初始连接到的onCreate(),所以按钮将只处理发送和在连接之前建立。
  • 在发送消息之后,去除关闭套接字
android c tcp client-server
1个回答
1
投票

我设法得到了这个工作。

我改了行

new SendMessageTask().execute(message);

new SendMessageTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);

这让发工作。

我也改变了服务器的代码如下:

#define MAX 2048
#define PORT 7891
#define SA struct sockaddr

// Function designed for chat between client and server.
void communicate(int sockfd)
{
    char buff[MAX];
    int n;
    // infinite loop for chat
    for (;;) {
        bzero(buff, MAX);

        // read the message from client and copy it in buffer
        read(sockfd, buff, sizeof(buff));
        // print buffer which contains the client contents
        printf("From client: %s\t To client : ", buff);
        bzero(buff, MAX);
        n = 0;
        // copy server message in the buffer
        while ((buff[n++] = getchar()) != '\n');

        // and send that buffer to client
        write(sockfd, buff, sizeof(buff));

        // if msg contains "Exit" then server exit and chat ended.
        if (strncmp("exit", buff, 4) == 0) {
            printf("Server Exit...\n");
            break;
        }

    }
}

// Driver function
int main()
{
    int sockfd, connfd, len;
    struct sockaddr_in servaddr, cli;

    // socket create and verification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully created..\n");
    bzero(&servaddr, sizeof(servaddr));

    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(PORT);

    // Binding newly created socket to given IP and verification
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
        printf("socket bind failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully binded..\n");

    // Now server is ready to listen and verification
    if ((listen(sockfd, 5)) != 0) {
        printf("Listen failed..\n");
        exit(0);
    }
    else
        printf("Server listening...\n");
    len = sizeof(cli);

    // Accept the data packet from client and verification
    connfd = accept(sockfd, (SA*)&cli, &len);
    if (connfd < 0) {
        printf("server acccept failed...\n");
        exit(0);
    }
    else
        printf("server acccept the client..\n");

    // Function for chatting between client and server
    communicate(connfd);

    // After chatting close the socket
    if(close(sockfd) < 0){
        printf("Error - closing socket...\n");
    }
    else{
        printf("Socket successfully closed..\n");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.