Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/214.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 非常简单的TCP客户端_Android_Tcp - Fatal编程技术网

Android 非常简单的TCP客户端

Android 非常简单的TCP客户端,android,tcp,Android,Tcp,我想用我的应用程序输入我服务器的url,例如http://192.168.1.8/和端口,例如1234。 当我的服务器收到TCP请求消息时,它会发回一个文件(服务器已经实现) 我认为我不需要像异步任务这样复杂的东西,因为我不想保持连接。收到服务器的答复后,我的连接必须关闭 非常感谢您提供任何前进方向或提示。这里是一个简单的TCP客户端,它使用的套接字是我根据中的代码工作的(教程的代码也可以找到) 注意,这段代码用于在客户端和服务器之间来回发送字符串,通常是JSON格式 以下是TCP客户端代码:

我想用我的应用程序输入我服务器的url,例如
http://192.168.1.8/
和端口,例如
1234
。 当我的服务器收到TCP请求消息时,它会发回一个文件(服务器已经实现)

我认为我不需要像异步任务这样复杂的东西,因为我不想保持连接。收到服务器的答复后,我的连接必须关闭


非常感谢您提供任何前进方向或提示。

这里是一个简单的TCP客户端,它使用的套接字是我根据中的代码工作的(教程的代码也可以找到)

注意,这段代码用于在客户端和服务器之间来回发送字符串,通常是JSON格式

以下是TCP客户端代码:

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.1.8"; //server IP address
    public static final int SERVER_PORT = 1234;
    // 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();
                }
            }
        };
        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);
    }

}
然后,将TcpClient声明为活动中的成员变量:

public class MainActivity extends Activity {

    TcpClient mTcpClient;

    //............
然后,使用AsyncTask连接到服务器并在UI线程上接收响应(请注意,从服务器接收的消息在AsyncTask中的
onProgressUpdate()
方法覆盖中处理):

然后,向服务器发送消息:

//sends the message to the server
if (mTcpClient != null) {
    mTcpClient.sendMessage("testing");
}
您可以随时关闭与服务器的连接:

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

谢谢你的代码。在我的例子中,我在接收数据时遇到了问题,因为我没有使用基于线路的协议。 我编写了一个与我的特定服务器设置配合使用的替代实现:

  • 在TcpClient.java文件中,“run()”命令应替换为下面的代码片段

    公开募捐{

  • //代码的其余部分还可以,请参阅原文

  • 在MainActivity.java中的DoinBackground将收到的消息发布到onProgressUpdate,您可以在其他对象(例如TextView)中显示该消息

    @Override
    protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            Log.d("test", "response " + values[0]);
            response.setText(response.getText() + "/n" +values[0]);
    } 
    
  • //“response”是在函数中声明的TextView对象

    public class MainActivity extends AppCompatActivity {
    TextView response; //...so on
    
    和功能

    创建时受保护的void(Bundle savedInstanceState){
    
    response=(TextView)findViewById(R.id.TextView);/…依此类推

    在TcpClient中尝试以下代码:

     public void run() {
            mRun = true;
            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
                Log.e("TCP Client", "C: Connecting...");
                Socket socket = new Socket(serverAddr, SERVER_PORT);
                try {
                    mBufferOut = new PrintWriter(socket.getOutputStream());
                    Log.e("TCP Client", "C: Sent.");
                    mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    int charsRead = 0; char[] buffer = new char[2024]; //choose your buffer size if you need other than 1024
                    while (mRun) {
                        charsRead = mBufferIn.read(buffer);
                        mServerMessage = new String(buffer).substring(0, charsRead);
                        if (mServerMessage != null && mMessageListener != null) {
                            Log.e("in if---------->>", " Received : '" + mServerMessage + "'");
                        }
                        mServerMessage = null;
                    }
                    Log.e("-------------- >>", " Received : '" + 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();
                    Log.e("-------------- >>", "Close socket " );
                }
    
            } catch (Exception e) {
                Log.e("TCP", "C: Error", e);
            }
    
        }
    
    它工作正常。这一行在上面的其他代码中导致错误

    mMessageListener.messageReceived(mServerMessage)

    删除这一行,你的应用程序就能正常运行。你也可以在android studio中监视你的日志

    您可以将此代码用于Golang中的服务器。这是我的服务器:

    package main
    
    import (
        "bufio"
        "flag"
        "fmt"
        "net"
        "strconv"
    )
    var addr = flag.String("addr", "", "The address to listen to; default is \"\" (all interfaces).")
    var port = flag.Int("port", 37533, "The port to listen on; default is 37533.")
    func main() {
        flag.Parse()
        fmt.Println("Starting server...")
        src := *addr + ":" + strconv.Itoa(*port)
        listener, _ := net.Listen("tcp", src)
        fmt.Printf("Listening on %s.\n", src)
    
        defer listener.Close()
    
        for {
            conn, err := listener.Accept()
            if err != nil {
                fmt.Printf("Some connection error: %s\n", err)
            }
            go handleConnection(conn)
        }
    }
    
    func handleConnection(conn net.Conn) {
        remoteAddr := conn.RemoteAddr().String()
      LocalAddr :=conn.LocalAddr().String()
    
      fmt.Println("Client LocalAddr  " + LocalAddr)
        fmt.Println("Client connected from " + remoteAddr)
        scanner := bufio.NewScanner(conn)
        for {
            ok := scanner.Scan()
    
            if !ok {
                break
            }
    
            handleMessage(scanner.Text(), conn)
        }
        fmt.Println("Client at " + remoteAddr + " disconnected.")
    }
    
    func handleMessage(message string, conn net.Conn) {
        fmt.Println("> " + message)
        if len(message) > 0 {
        conn.Write([]byte("This is from Golang.\n"))
        fmt.Println("----------> we send it....")
        }
    }
    

    首先,在android清单中为你的应用程序授予互联网权限

    <uses-permission android:name="android.permission.INTERNET"/>
    

    最终的部署环境是什么?您的代码指向本地IP。当您将其部署到真正的服务器环境时,可能会发生更改? 如果您在托管服务器中启动此代码,请注意NAT问题。这样您将无法获取数据包。
    考虑使用一个更复杂的协议(例如,Socket.io可以帮助)< /P> > 3件事:<代码> AycCastase/Co>根本不复杂;你确实需要一些东西,比如“代码> AycCastase”(否则你将得到<代码> Android .OS.NETWorksMouthSuxAddixPosip);查阅库<代码>改版 >它很容易管理你所需要的一切。(每个人都使用它)@G.v听起来好像你实际上在GET请求中使用http和查询字符串,而不是tcp…别忘了将
    添加到你的
    AndroidManifest.xml
    @pkpkpkpk我猜新的操作系统版本对此要求更严格,原始代码非常旧,并且在旧的操作系统版本上工作。我刚刚更改了使用链接到的修复程序进行回答。-1“异步任务最好用于短期操作(最多几秒钟)。”这是我尝试学习android的第二天。过去我对C语言中的tcp/ip非常熟悉,我发现上面的代码片段很好地说明了与低级和高级交互相关的安排和抽象。谢谢。你指/感谢什么代码?这更多的是对不同答案的评论吗?也许是一个which已被删除?是否要将其更改为独立的答案?代码位于顶部网页,线程名为“Really simple TCP client”还是我看到了不同的东西?在上面我看到一个问题,没有代码。在中间我看到了一个答案,用代码。如果你提到这个答案,请读上面的评论。也就是说,你想做出一个独立的答案吗?可能会有更多的答案,用不同的好代码。不清楚你指的是什么。你可以WRI。这是一个建立在目前唯一答案基础上的答案,但你应该更清楚地提及。问题是,你的答案目前看起来可能像是“应该是评论的答案”。但是,既然你同时获得了一张赞成票(祝贺你),可能只有我一个人。祝你玩得开心。第一次发布到这个网页上,可能是因为我对规则不太熟悉(很抱歉)。但当你花半天时间让事情顺利进行时,你所需要的东西是非常清楚的,不管评论指什么…:)。但是谢谢你的评论,下次我会尽量说得更准确。(顺便说一句,独立答案需要复制作者发布的原始代码,而不仅仅是更正的片段,所以我不确定这是否是个好主意)。关于。如果你主要复制其他答案代码,那么你可以在该答案的基础上写一个答案(不是复制,你是对的),但要更清楚地引用,例如“Daniel Nugent的回答”。一段时间过去了。看起来不像我所担心的(更多的答案)现在会发生。所以你很好。仍然没有否决票,所以你最好实际上忽略我。如果你发现(为了将来的参与)在我的评论中有一些有用的东西,然后感谢你的赞美。让你的第一个答案投赞成票而不是反对票是一项成就。期待从你那里读到更多。不适合我。如文档所示,
    android.os.AsyncTask
    将被避免和弃用。由于某些原因,它会导致错过回调和其他问题因此,任何添加项都不能声称在该代码段的基础上派生了更持久的构造。感谢您对代码进行了修改,以尝试构建更可靠的代码。仅供参考,服务器代码不会
     public void run() {
            mRun = true;
            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
                Log.e("TCP Client", "C: Connecting...");
                Socket socket = new Socket(serverAddr, SERVER_PORT);
                try {
                    mBufferOut = new PrintWriter(socket.getOutputStream());
                    Log.e("TCP Client", "C: Sent.");
                    mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    int charsRead = 0; char[] buffer = new char[2024]; //choose your buffer size if you need other than 1024
                    while (mRun) {
                        charsRead = mBufferIn.read(buffer);
                        mServerMessage = new String(buffer).substring(0, charsRead);
                        if (mServerMessage != null && mMessageListener != null) {
                            Log.e("in if---------->>", " Received : '" + mServerMessage + "'");
                        }
                        mServerMessage = null;
                    }
                    Log.e("-------------- >>", " Received : '" + 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();
                    Log.e("-------------- >>", "Close socket " );
                }
    
            } catch (Exception e) {
                Log.e("TCP", "C: Error", e);
            }
    
        }
    
    package main
    
    import (
        "bufio"
        "flag"
        "fmt"
        "net"
        "strconv"
    )
    var addr = flag.String("addr", "", "The address to listen to; default is \"\" (all interfaces).")
    var port = flag.Int("port", 37533, "The port to listen on; default is 37533.")
    func main() {
        flag.Parse()
        fmt.Println("Starting server...")
        src := *addr + ":" + strconv.Itoa(*port)
        listener, _ := net.Listen("tcp", src)
        fmt.Printf("Listening on %s.\n", src)
    
        defer listener.Close()
    
        for {
            conn, err := listener.Accept()
            if err != nil {
                fmt.Printf("Some connection error: %s\n", err)
            }
            go handleConnection(conn)
        }
    }
    
    func handleConnection(conn net.Conn) {
        remoteAddr := conn.RemoteAddr().String()
      LocalAddr :=conn.LocalAddr().String()
    
      fmt.Println("Client LocalAddr  " + LocalAddr)
        fmt.Println("Client connected from " + remoteAddr)
        scanner := bufio.NewScanner(conn)
        for {
            ok := scanner.Scan()
    
            if !ok {
                break
            }
    
            handleMessage(scanner.Text(), conn)
        }
        fmt.Println("Client at " + remoteAddr + " disconnected.")
    }
    
    func handleMessage(message string, conn net.Conn) {
        fmt.Println("> " + message)
        if len(message) > 0 {
        conn.Write([]byte("This is from Golang.\n"))
        fmt.Println("----------> we send it....")
        }
    }
    
    <uses-permission android:name="android.permission.INTERNET"/>
    
        public void send_request() {
        send_request sr = new send_request();
        sr.execute();
    }
    
    class send_request extends AsyncTask<Void, Void, String> {
    
        @Override
        protected String doInBackground(Void... voids) {
            try {             /*note : ip address must be in Quotation mark*/
                              /*note : port doesn't need to be inside the Quotation mark*/
                Socket s = new Socket(/*ip address :*/"192.168.1.8",/*port :*/ 1234);
                PrintWriter printWriter = new PrintWriter(s.getOutputStream());
                printWriter.write("your message");
                printWriter.flush();
                printWriter.close();
                s.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public void onPostExecute(final String Data) {
            /*Data is what you receive from your server*/
            Log.e("my_Data","Data is : " + Data);
        }
    }