最近学socket,遇到如下问题:
1.Andorra4.4是必须把socket网络连接放到线程中的,放到ui线程会出错。
2.这一点最坑爹,坑了我两天了。采用
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
String string = br.readLine();
System.out.println(string);
读取客户端socket发来的数据时,一直不能读出来,起初是怀疑线程同步的问题,同步锁啊,静态变量啊都用
了,依然不行,最后发现真正元凶是:用socket方式,readline如果没有得到数据会一直阻塞.得到数据也一定要读到回车才能继续,否则还是阻塞。也就是说,在线程中写数据的时候有:
Socket socket = new Socket("172.27.35.1", 30000);
os = socket.getOutputStream();
String string = "hello" + "\r\n";
os.write(string.getBytes("utf-8"));
必须加\r。\r是回车。\n是换行。
3.还有一个重要问题:
Message msg = new Message(); while (count<4) { count++; msg.what = count; myHandler.sendMessage(msg);
}
出错原因知道,只要将Message msg = new Message();移到while语句里面就正常运行放在while语句外面时,你只有一个Message对象,该对象通过sendMessage()被发送,然后在handleMessage()中得到处理,而此时你的循环仍在运行,又对该对象进行赋值。导致的结果是两个线程可能同时处理一个对象,就出错了。而放在while里面的话,每次循环开始,都重新创建了一个message对象,你是针对不同对象进行操作的,故没有问题了。
4.主线程向子线程发送消息,需要在子线程中写个handler,然后在run()中new出来,问题是如何在主线程中得到子线程的handler呢?
可以在子线程中写个getHandler()方法,但是必须加锁,原因是必须等到线程中把Handler初始化结束后才能通过getHandler传出去。
package com.example.serverdemoclient; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.Socket; import java.net.UnknownHostException; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; public class SendThread extends Thread { public Handler mHandler; Looper mlooper = null; String string; private final Object mSync = new Object(); OutputStream os; public Handler getHandler() { synchronized (mSync) { if(mHandler == null) try { mSync.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return mHandler; } @Override public void run() { Looper.prepare(); try { Socket socket = new Socket("172.27.35.1", 30000); os = socket.getOutputStream(); String string = "hello" + "\r\n"; os.write(string.getBytes("utf-8")); Log.i("tag", "write complet"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (mSync) { mHandler = new Handler() { @Override public void handleMessage(Message msg) { Log.i("tag", "new Handler"); string = msg.obj.toString(); try { os.write((string + "\r\n").getBytes("utf-8")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; mSync.notifyAll(); } Looper.loop(); } }