前言:将socket开启,发送和接收分开在3个子线程,发送和接收数据互不影响。
public class StartSocketThread implements Runnable {
public static Socket socket;
Message msg_main = MainActivity.myhandler.obtainMessage();//////////////
@Override
public void run() {
try {
String socket_ip = DeviceMsg.getAddress();
String socket_port = DeviceMsg.getPort();
if (socket_ip==null || socket_port=="") {
return;
}
int Socket_port = Integer.parseInt(socket_port);
socket = new Socket(socket_ip,Socket_port);//连接服务端的IP
MainActivity.running = true;//socket线程运行中标志位
if(socket.isConnected()&&!socket.isClosed()){//成功连接socket对象
//启动接收数据的线程
new Thread(new SocketReceiveThread(socket)).start();
//启动发送数据的线程
new Thread(new SocketSendThread(socket)).start();
//发送连接成功消息到主线程
msg_main.what=Const.ConnectSuccess;
MainActivity.myhandler.sendMessage(msg_main);
}
}catch (Exception e) {
e.printStackTrace();
//利用Handler返回数据(连接失败)到主线程
msg_main.what= Const.ConnectFail;
MainActivity.myhandler.sendMessage(msg_main);
MainActivity.running = false;
Log.e("StartThread:",e.getMessage());
}
}
}
public class SocketSendThread implements Runnable {
private OutputStream out = null;
public static boolean writing = false;
//建立构造函数来获取socket对象的输入流
public SocketSendThread(Socket socket) throws IOException {
out = socket.getOutputStream();//得到socket的输出流
}
@Override
public void run() {
// 发送请求数据
while (MainActivity.running) {
try {
while (writing == true) {
writing = false;
byte[] codeToSend = CodeList.getCodeToSend();
out.write(codeToSend);
String str = new String(codeToSend);
}
//数据最后加上换行符才可以让服务器端的readline()停止阻塞
// out.write((str).getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class SocketReceiveThread implements Runnable {
private InputStream is;
private String str_receive;
private String Tag = "SocketReceiveThread";
//建立构造函数来获取socket对象的输入流
public SocketReceiveThread(Socket socket) throws IOException {
is = socket.getInputStream();
}
@Override
public void run() {
while (MainActivity.running) {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
//用Handler把读取到的信息发到主线程
Message msg0 = MainActivity.myhandler.obtainMessage();
try {
//读服务器端发来的数据,阻塞直到收到结束符\n或\r
// str_receive = br.readLine();
//非阻塞接收数据,但限定接收数据字节
byte buffer[] = new byte[1024*30];
int count = is.read(buffer);
if(count != -1){
str_receive = new String(buffer,0,count);
}else { MainActivity.running = false;StartSockerThreat.socket.close();
return;}
} catch (NullPointerException e) {
e.printStackTrace();
Log.e(Tag,e.getMessage());
MainActivity.running = false;//防止服务器端关闭导致客户端读到空指针而导致程序崩溃
msg0.what = Const.ServiceDisconnect;
MainActivity.myhandler.sendMessage(msg0);//发送信息通知用户客户端已关闭
break;
} catch (IOException e) {
e.printStackTrace();
Log.e(Tag,e.getMessage());
MainActivity.running = false;//防止服务器端关闭导致客户端读到空指针而导致程序崩溃
msg0.what = Const.ServiceDisconnect;
MainActivity.myhandler.sendMessage(msg0);//发送信息通知用户客户端已关闭
break;
}
// Message msg0 = MainActivity.myhandler.obtainMessage();
// msg0.what = 1;//把读到的内容更新到UI
// msg0.obj = str_receive;
// MainActivity.myhandler.sendMessage(msg0);
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e(Tag,e.getMessage());
}
}
}
}
public class MainActivity extends BaseActivity {
private String Tag = "MainActivity";
public static Handler myhandler;
//socket线程是否running的标志位
public static boolean running = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//去除标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏
setContentView(R.layout.activity_main);
//实例化Handler,用于进程间的通信//////////////////
myhandler = new MyHandler();
//启动Socket线程
new Thread(new StartSocketThread()).start();
}
class MyHandler extends Handler{//在主线程处理Handler传回来的message
@Override
public void handleMessage(Message msg) {
// Intent intent = new Intent("com.example.BroadcastReceiver.MY_BROADCAST");
String currentActivityName = ActivityName.getName();
switch (msg.what) {
case 1:
String str = (String) msg.obj;
Log.i("received:",str);
break;
case Const.ConnectSuccess:
Log.i("handleMessage_Socket", "连接成功");
Toast.makeText(MyApplication.getContext(),
"连接成功!", Toast.LENGTH_SHORT).show();
break;
case Const.ServiceDisconnect:
Log.i("handleMessage_Socket", "服务端连接断开");
Toast.makeText(MyApplication.getContext(),
"与服务器断开连接!", Toast.LENGTH_SHORT).show();
break;
case Const.ConnectFail:
Log.i("handleMessage_Socket", "连接失败");
Toast.makeText(MyApplication.getContext(),
"连接失败", Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
}
/**
* 销毁activity
*/
@Override
protected void onDestroy(){
super.onDestroy();
if(broadcastReceiver != null){
unregisterReceiver(broadcastReceiver);//取消注册广播
}
if (StartSocketThread.socket == null) {
return;
}
try {
//关闭Socket线程
this.running = false;
StartSocketThread.socket.close();
} catch (NullPointerException | IOException e) {
e.printStackTrace();
}
}
}
String code = "哈哈";
CodeList.setCodeToSend(code.getBytes());
SocketSendThread.writing = true;