我只是在 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;
}
}