0

我只是在 Android 上学习套接字通信。由于我认为这是最简单的演示,我制作了一个立即开始收听的应用程序,当用户按下按钮时,它会将 EditText 中的文本发送给自己,并在 LogCat 中显示接收到的消息。我的理解是ServerSocket serverSocket = new ServerSocket(port);在收到连接之前会一直阻塞。下面的代码永远不会命中Log.i("Listen()", "accepted.");,所以我假设永远不会建立连接。当我单击 btnSendMessage 时,Log.i("Send()", "Message sent.");运行,但似乎没有其他任何事情发生。我在想这Socket socket = new Socket(address, port);就是让 ServerSocket 继续运行的原因。

有人看到以下有什么问题吗?

package com.example.socketdemo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity
{
    // UI elements
    Button btnSendMessage = null;
    TextView tvReceivedMessage = null;
    EditText textMessage = null;

    int port = 9000;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        Log.i("onCreate()", "onCreate()");

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSendMessage = (Button) findViewById(R.id.btnSendMessage);
        btnSendMessage.setOnClickListener(btnSendMessage_OnClickListener);

        textMessage = (EditText) findViewById(R.id.textMessage);

        tvReceivedMessage = (TextView) findViewById(R.id.tvReceivedMessage);

        Listen();
    }

    Thread thread = null;

    private void Listen()
    {
        Log.i("Listen()", "Listen()");

        thread = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    ServerSocket serverSocket = new ServerSocket(port);
                    Socket clientSocket = serverSocket.accept();
                    Log.i("Listen()", "accepted.");

                    BufferedReader bufferedReader = new BufferedReader(
                            new InputStreamReader(clientSocket.getInputStream()));

                    while (true)
                    {
                        Thread.sleep(500);
                        String receivedLine = bufferedReader.readLine();
                        Log.i("Listen()", receivedLine);
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }

    private void Send(final String address, final String message)
    {
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    Socket socket = new Socket(address, port);

                    // Attempt #1
                    // DataOutputStream dataOutputStream = new
                    // DataOutputStream(socket.getOutputStream());
                    // dataOutputStream.writeUTF(message);

                    // Attempt #2 (what is different about this than attempt
                    // #1?)
                    PrintWriter out = new PrintWriter(new BufferedWriter(
                            new OutputStreamWriter(socket.getOutputStream())),
                            true);
                    out.println(message);

                    socket.close();
                    Log.i("Send()", "Message sent.");
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }

    private OnClickListener btnSendMessage_OnClickListener = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            // Get the address to send to from the UI
            EditText textAddress = (EditText) findViewById(R.id.textAddress);
            String destinationAddress = textAddress.getText().toString();

            textMessage = (EditText) findViewById(R.id.textMessage);
            String message = textMessage.getText().toString();

            Send(destinationAddress, message);
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

- - - - - - - - 编辑 - - - - - - - -

事实证明,这确实是可能的。我不确定我做错了什么,但这段代码按预期工作:

package com.example.socketdemo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity
{
    // UI elements
    Button btnSendMessage = null;
    Button btnListen = null;
    TextView tvReceivedMessage = null;
    EditText textMessage = null;

    int port = 9000;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        Log.i("onCreate()", "onCreate()");

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSendMessage = (Button) findViewById(R.id.btnSendMessage);
        btnSendMessage.setOnClickListener(btnSendMessage_OnClickListener);

        btnListen = (Button) findViewById(R.id.btnListen);
        btnListen.setOnClickListener(btnListen_OnClickListener);

        textMessage = (EditText) findViewById(R.id.textMessage);

        tvReceivedMessage = (TextView) findViewById(R.id.tvReceivedMessage);
    }

    Thread thread = null;

    private void Listen()
    {
        Log.i("Listen()", "Listen()");

        thread = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    ServerSocket serverSocket = new ServerSocket(port);
                    Socket clientSocket = serverSocket.accept();
                    Log.i("Listen()", "accepted.");

                    BufferedReader bufferedReader = new BufferedReader(
                            new InputStreamReader(clientSocket.getInputStream()));

                    // Listen until we receive a message or the client disconnects
                    boolean stopListening = false;
                    while (!stopListening)
                    {
                        Thread.sleep(500);
                        String receivedLine = bufferedReader.readLine();
                        if(receivedLine != null)
                        {
                            Log.i("Listen()", "Received message: " + receivedLine);
                            stopListening = true;
                        }

                        // Check if the client has disconnected by attempting to write to him (this is the recommended technique)
                        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                        if (out.checkError())
                        {
                            stopListening = true;
                            Log.i("Listen()", "Client disconnected.");
                        }
                    }

                    clientSocket.close();                    

                }
                catch (Exception e)
                {
                    Log.i("Listen()", "Exception caught!");
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }

    private void Send(final String address, final String message)
    {
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                Socket mSendSocket = null; 

                try
                {
                    if(mSendSocket == null)
                    {
                        Log.i("Send::run()", "Creating socket to " + address);
                        mSendSocket = new Socket(address, port);
                    }

                    // Send ascii data
                    PrintWriter out = new PrintWriter(new BufferedWriter(
                            new OutputStreamWriter(mSendSocket.getOutputStream())),
                            true);
                    out.println(message);

                    Log.i("Send()", "Message sent.");
                }
                catch (IOException e)
                {
                    if(e instanceof UnknownHostException)
                    {
                        Log.i("Send()", "Unknown host.");    
                    }
                    else
                    {
                        Log.i("Send()", "Connection failed.");
                    }
                }

            }
        });

        thread.start();
    }

    private OnClickListener btnSendMessage_OnClickListener = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            // Get the address to send to from the UI
            EditText textAddress = (EditText) findViewById(R.id.textAddress);
            String destinationAddress = textAddress.getText().toString();

            textMessage = (EditText) findViewById(R.id.textMessage);

            String message = textMessage.getText().toString();

            Send(destinationAddress, message);
        }
    };

    private OnClickListener btnListen_OnClickListener = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Listen();
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
4

0 回答 0