Android - 在单独的线程中连接到套接字
Android - Connect to socket in separate thread
我正在尝试在 Android 中创建一个非常非常简单的服务器-客户端应用程序。
服务器在我的电脑上是 运行,它是用 python 编写的。 (只是一个简单的 while (true) 循环,它接收一个字符串并用另一个字符串进行响应。)
问题出在 Android 客户端。所以我试图在一个单独的线程中创建一个单例 class,其中:
- 创建套接字
- 连接到套接字
- 可以通过其他活动访问
- 写入套接字
- 从套接字读取
我尝试写入和读取其他异步任务。
它一直有效,直到我再次尝试写入套接字。 (1 次写入正常,任何其他尝试均失败。)我没有收到任何异常,我检查了套接字是否关闭或写入器是否为空等。消息只是没有写入套接字。
这个解决方案有什么问题? :/
你能帮帮我吗?
这是主题:
public class ConnectThread extends Thread
{
// singleton Part
private static class ThreadHolder {
static final ConnectThread instance = new ConnectThread();
}
public static synchronized ConnectThread getInstance(){
if(ThreadHolder.instance == null)
Log.d("mytag", "NEW INSTANCE CREATED");
// return (ThreadHolder.instance == null) ? ThreadHolder.instance = new ConnectThread() : ThreadHolder.instance;
return ThreadHolder.instance;
}
private ConnectThread(){
}
// implementation part
private Socket mSocket;
private BufferedWriter socketWriter;
private BufferedReader socketReader;
public Socket getSocket() {
return mSocket;
}
public void WriteToSocket(String msg)
{
try{
if(!(mSocket.isClosed()))
{
Log.d("mytag", "Writing to socket");
if(socketWriter == null)
Log.d("mytag", "Writer closed - in write to socket");
socketWriter.write(msg);
socketWriter.flush();
}else
Log.d("mytag", "CANT write to socket");
}catch(IOException e)
{
e.printStackTrace();
Log.d("mytag", e.toString());
}
}
public String ReadFromSocket()
{
try
{
if(!(mSocket.isClosed())) {
Log.d("mytag", "Reading from socket");
if(socketReader == null)
{
Log.d("mytag", "Reader closed - in read from socket");
}
return socketReader.readLine();
}else
{
Log.d("mytag", "CANT from socket");
return null;
}
}catch (IOException e)
{
e.printStackTrace();
return null;
}
}
@Override
public void run() {
try
{
mSocket = new Socket();
mSocket.setKeepAlive(true);
try
{
mSocket.setTcpNoDelay(true);
}
catch (SocketException e)
{
}
mSocket.connect(new InetSocketAddress("192.168.0.128", 8888), 2000);
if(!(mSocket.isClosed()))
{
Log.d("mytag", "SOCKET IS RUNNING");
socketWriter = new BufferedWriter(new OutputStreamWriter(this.mSocket.getOutputStream()));
socketReader = new BufferedReader(new InputStreamReader(this.mSocket.getInputStream()));
if(socketWriter == null)
{
Log.d("mytag", "WRITER NOT CREATED");
}else
Log.d("mytag", "WRITER READY");
if(socketReader == null)
{
Log.d("mytag", "READER NOT CREATED");
}else
Log.d("mytag", "READER READY");
}
}catch (IOException e)
{
e.printStackTrace();
}
}
}
这里是读取、写入的尝试:
@Override
protected Void doInBackground(Void... params)
{
PrintDebugMsg("do in background");
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Checking network availability...");
//progressDialog.setTitle("Checking network availability...");
//check network:
ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(parentContext.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if(netInfo != null && netInfo.isConnected())
{
networkAvail = true;
response += "| Network available |";
}
PrintDebugMsg("do in background 2");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
changeStatusImg(imgvNetworkStatus, networkAvail?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Pinging server");
//progressDialog.setTitle("Pinging server...");
//check server status
try {
PrintDebugMsg("do in background 3");
if(!(ConnectThread.getInstance().getSocket().isClosed()))
{
ConnectThread.getInstance().WriteToSocket(PING_FROM_DROID);
String line = "";
line = ConnectThread.getInstance().ReadFromSocket();
if(line.equals(PING_ACK))
{
serverAvail = true;
response += " | pinged |";
PrintDebugMsg("do in background 4", true);
}
}
else{
response += " | NOT pinged |";
PrintDebugMsg("do in background 5", true);
throw new UnknownHostException();
}
PrintDebugMsg("do in background 6", true);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response += " | UnknownHostException: " + e.toString() + " - during server check |";
PrintDebugMsg("do in background 7", true);
} finally{
PrintDebugMsg("do in background 9", true);
if(ConnectThread.getInstance().getSocket() != null){
}
}
PrintDebugMsg("do in background 10", true);
if(serverAvail)
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
changeStatusImg(imgvServerStatus, serverAvail?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Connectiong to server...");
//connect to server:
try {
PrintDebugMsg("do in background 11",true);
//socket = new Socket(dstAddress, dstPort);
//socket = ConnectThread.getInstance().getSocket();
PrintDebugMsg("do in background 12",true);
if(!(ConnectThread.getInstance().getSocket().isClosed())) {
PrintDebugMsg("do in background 13",true);
PrintDebugMsg("do in background 14",true);
PrintDebugMsg("do in background 15",true);
ConnectThread.getInstance().WriteToSocket(CONN_REQ_FROM_DROID);
String line = "";
line = ConnectThread.getInstance().ReadFromSocket();
PrintDebugMsg("conn line = " + line, true);
if(line != null && line.equals(CONN_ACK))
{
connected = true;
response += "| connected |";
PrintDebugMsg("do in background 12");
}
}else
{
response += "| NOT connected |";
PrintDebugMsg("do in background 13");
throw new UnknownHostException();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response += " | UnknownHostException: " + e.toString() + " - during connecting |";
}finally{
PrintDebugMsg("connection finished");
}
if(connected) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
changeStatusImg(imgvConnectionStatus, connected?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------
------------
return null;
}
"util"函数:
private void PrintDebugMsg(String msg, boolean b)
{
if(b)
Log.d("mytag", msg);
}
private void changeProgressMsg(final ProgressDialog dialog,final String value){
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.setMessage(value);
}
});
}
private void changeStatusImg(final ImageView imgView, final int imgId){
runOnUiThread(new Runnable() {
@Override
public void run() {
imgView.setImageResource(imgId);
}
});
}
Sever.java
public class Server {
public static void main(String[] args) {
new Server().startServer();
}
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8000);
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
System.err.println("Unable to process client request");
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
System.out.println("Got a client !");
// Do whatever required to process the client's request
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我正在尝试在 Android 中创建一个非常非常简单的服务器-客户端应用程序。 服务器在我的电脑上是 运行,它是用 python 编写的。 (只是一个简单的 while (true) 循环,它接收一个字符串并用另一个字符串进行响应。) 问题出在 Android 客户端。所以我试图在一个单独的线程中创建一个单例 class,其中:
- 创建套接字
- 连接到套接字
- 可以通过其他活动访问
- 写入套接字
- 从套接字读取
我尝试写入和读取其他异步任务。 它一直有效,直到我再次尝试写入套接字。 (1 次写入正常,任何其他尝试均失败。)我没有收到任何异常,我检查了套接字是否关闭或写入器是否为空等。消息只是没有写入套接字。
这个解决方案有什么问题? :/
你能帮帮我吗?
这是主题:
public class ConnectThread extends Thread
{
// singleton Part
private static class ThreadHolder {
static final ConnectThread instance = new ConnectThread();
}
public static synchronized ConnectThread getInstance(){
if(ThreadHolder.instance == null)
Log.d("mytag", "NEW INSTANCE CREATED");
// return (ThreadHolder.instance == null) ? ThreadHolder.instance = new ConnectThread() : ThreadHolder.instance;
return ThreadHolder.instance;
}
private ConnectThread(){
}
// implementation part
private Socket mSocket;
private BufferedWriter socketWriter;
private BufferedReader socketReader;
public Socket getSocket() {
return mSocket;
}
public void WriteToSocket(String msg)
{
try{
if(!(mSocket.isClosed()))
{
Log.d("mytag", "Writing to socket");
if(socketWriter == null)
Log.d("mytag", "Writer closed - in write to socket");
socketWriter.write(msg);
socketWriter.flush();
}else
Log.d("mytag", "CANT write to socket");
}catch(IOException e)
{
e.printStackTrace();
Log.d("mytag", e.toString());
}
}
public String ReadFromSocket()
{
try
{
if(!(mSocket.isClosed())) {
Log.d("mytag", "Reading from socket");
if(socketReader == null)
{
Log.d("mytag", "Reader closed - in read from socket");
}
return socketReader.readLine();
}else
{
Log.d("mytag", "CANT from socket");
return null;
}
}catch (IOException e)
{
e.printStackTrace();
return null;
}
}
@Override
public void run() {
try
{
mSocket = new Socket();
mSocket.setKeepAlive(true);
try
{
mSocket.setTcpNoDelay(true);
}
catch (SocketException e)
{
}
mSocket.connect(new InetSocketAddress("192.168.0.128", 8888), 2000);
if(!(mSocket.isClosed()))
{
Log.d("mytag", "SOCKET IS RUNNING");
socketWriter = new BufferedWriter(new OutputStreamWriter(this.mSocket.getOutputStream()));
socketReader = new BufferedReader(new InputStreamReader(this.mSocket.getInputStream()));
if(socketWriter == null)
{
Log.d("mytag", "WRITER NOT CREATED");
}else
Log.d("mytag", "WRITER READY");
if(socketReader == null)
{
Log.d("mytag", "READER NOT CREATED");
}else
Log.d("mytag", "READER READY");
}
}catch (IOException e)
{
e.printStackTrace();
}
}
}
这里是读取、写入的尝试:
@Override
protected Void doInBackground(Void... params)
{
PrintDebugMsg("do in background");
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Checking network availability...");
//progressDialog.setTitle("Checking network availability...");
//check network:
ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(parentContext.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if(netInfo != null && netInfo.isConnected())
{
networkAvail = true;
response += "| Network available |";
}
PrintDebugMsg("do in background 2");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
changeStatusImg(imgvNetworkStatus, networkAvail?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Pinging server");
//progressDialog.setTitle("Pinging server...");
//check server status
try {
PrintDebugMsg("do in background 3");
if(!(ConnectThread.getInstance().getSocket().isClosed()))
{
ConnectThread.getInstance().WriteToSocket(PING_FROM_DROID);
String line = "";
line = ConnectThread.getInstance().ReadFromSocket();
if(line.equals(PING_ACK))
{
serverAvail = true;
response += " | pinged |";
PrintDebugMsg("do in background 4", true);
}
}
else{
response += " | NOT pinged |";
PrintDebugMsg("do in background 5", true);
throw new UnknownHostException();
}
PrintDebugMsg("do in background 6", true);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response += " | UnknownHostException: " + e.toString() + " - during server check |";
PrintDebugMsg("do in background 7", true);
} finally{
PrintDebugMsg("do in background 9", true);
if(ConnectThread.getInstance().getSocket() != null){
}
}
PrintDebugMsg("do in background 10", true);
if(serverAvail)
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
changeStatusImg(imgvServerStatus, serverAvail?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Connectiong to server...");
//connect to server:
try {
PrintDebugMsg("do in background 11",true);
//socket = new Socket(dstAddress, dstPort);
//socket = ConnectThread.getInstance().getSocket();
PrintDebugMsg("do in background 12",true);
if(!(ConnectThread.getInstance().getSocket().isClosed())) {
PrintDebugMsg("do in background 13",true);
PrintDebugMsg("do in background 14",true);
PrintDebugMsg("do in background 15",true);
ConnectThread.getInstance().WriteToSocket(CONN_REQ_FROM_DROID);
String line = "";
line = ConnectThread.getInstance().ReadFromSocket();
PrintDebugMsg("conn line = " + line, true);
if(line != null && line.equals(CONN_ACK))
{
connected = true;
response += "| connected |";
PrintDebugMsg("do in background 12");
}
}else
{
response += "| NOT connected |";
PrintDebugMsg("do in background 13");
throw new UnknownHostException();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response += " | UnknownHostException: " + e.toString() + " - during connecting |";
}finally{
PrintDebugMsg("connection finished");
}
if(connected) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
changeStatusImg(imgvConnectionStatus, connected?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------
------------
return null;
}
"util"函数:
private void PrintDebugMsg(String msg, boolean b)
{
if(b)
Log.d("mytag", msg);
}
private void changeProgressMsg(final ProgressDialog dialog,final String value){
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.setMessage(value);
}
});
}
private void changeStatusImg(final ImageView imgView, final int imgId){
runOnUiThread(new Runnable() {
@Override
public void run() {
imgView.setImageResource(imgId);
}
});
}
Sever.java
public class Server {
public static void main(String[] args) {
new Server().startServer();
}
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8000);
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
System.err.println("Unable to process client request");
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
System.out.println("Got a client !");
// Do whatever required to process the client's request
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}