package com.ccf.feige.net; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Queue; import java.util.Vector; import java.util.concurrent.ConcurrentLinkedQueue; import android.os.Message; import android.util.Log; import com.ccf.feige.activity.MyFeiGeActivity; import com.ccf.feige.activity.MyFeiGeBaseActivity; import com.ccf.feige.data.ChatMessage; import com.ccf.feige.data.User; import com.ccf.feige.interfaces.ReceiveMsgListener; import com.ccf.feige.utils.IpMessageConst; import com.ccf.feige.utils.IpMessageProtocol; /** * �ɸ������ͨ�Ÿ����� * ʵ��UDPͨ���Լ�UDP�˿ڼ��� * �˿ڼ������ö��̷߳�ʽ * * ����ģʽ * @author ccf * * V1.0 2012/2/14����į�����˽ڰ汾���ٺ� * */ public class NetThreadHelper implements Runnable{ public static final String TAG = "NetThreadHelper"; private static NetThreadHelper instance; private static final int BUFFERLENGTH = 1024; //�����С private boolean onWork = false; //�̹߳�����ʶ private String selfName; private String selfGroup; private Thread udpThread = null; //����UDP�����߳� private DatagramSocket udpSocket = null; //���ڽ��պͷ���udp���ݵ�socket private DatagramPacket udpSendPacket = null; //���ڷ��͵�udp���ݰ� private DatagramPacket udpResPacket = null; //���ڽ��յ�udp���ݰ� private byte[] resBuffer = new byte[BUFFERLENGTH]; //�������ݵĻ��� private byte[] sendBuffer = null; private Map<String,User> users; //��ǰ�����û��ļ��ϣ���IPΪKEY private int userCount = 0; //�û�������ע�⣬����ֵֻ���ڵ���getSimpleExpandableListAdapter()�Ż���£�Ŀ������adapter���û���������һ�� private Queue<ChatMessage> receiveMsgQueue; //��Ϣ����,��û�����촰��ʱ�����յ���Ϣ�ŵ���������� private Vector<ReceiveMsgListener> listeners; //ReceiveMsgListener��������һ�����촰�ڴ�ʱ��������롣һ��Ҫ�ǵ���ʱ�����Ƴ� private NetThreadHelper(){ users = new HashMap<String, User>(); receiveMsgQueue = new ConcurrentLinkedQueue<ChatMessage>(); listeners = new Vector<ReceiveMsgListener>(); selfName = "android�ɸ�"; selfGroup = "android"; } public static NetThreadHelper newInstance(){ if(instance == null) instance = new NetThreadHelper(); return instance; } public Map<String, User> getUsers(){ return users; } public int getUserCount(){ return userCount; } public Queue<ChatMessage> getReceiveMsgQueue(){ return receiveMsgQueue; } //���listener�������� public void addReceiveMsgListener(ReceiveMsgListener listener){ if(!listeners.contains(listener)){ listeners.add(listener); } } //���������Ƴ���Ӧlistener public void removeReceiveMsgListener(ReceiveMsgListener listener){ if(listeners.contains(listener)){ listeners.remove(listener); } } /** * * �˷��������ж��Ƿ��д���ǰ̨�����촰�ڶ�Ӧ��activity�������յ������ݡ� */ private boolean receiveMsg(ChatMessage msg){ for(int i = 0; i < listeners.size(); i++){ ReceiveMsgListener listener = listeners.get(i); if(listener.receive(msg)){ return true; } } return false; } public void noticeOnline(){ // �������߹㲥 IpMessageProtocol ipmsgSend = new IpMessageProtocol(); ipmsgSend.setVersion(String.valueOf(IpMessageConst.VERSION)); ipmsgSend.setSenderName(selfName); ipmsgSend.setSenderHost(selfGroup); ipmsgSend.setCommandNo(IpMessageConst.IPMSG_BR_ENTRY); //�������� ipmsgSend.setAdditionalSection(selfName + "\0" ); //������Ϣ������û����ͷ�����Ϣ InetAddress broadcastAddr; try { broadcastAddr = InetAddress.getByName("255.255.255.255"); //�㲥��ַ sendUdpData(ipmsgSend.getProtocolString()+"\0", broadcastAddr, IpMessageConst.PORT); //�������� } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e(TAG, "noticeOnline()....�㲥��ַ����"); } } public void noticeOffline(){ //�������߹㲥 IpMessageProtocol ipmsgSend = new IpMessageProtocol(); ipmsgSend.setVersion(String.valueOf(IpMessageConst.VERSION)); ipmsgSend.setSenderName(selfName); ipmsgSend.setSenderHost(selfGroup); ipmsgSend.setCommandNo(IpMessageConst.IPMSG_BR_EXIT); //�������� ipmsgSend.setAdditionalSection(selfName + "\0" + selfGroup); //������Ϣ������û����ͷ�����Ϣ InetAddress broadcastAddr; try { broadcastAddr = InetAddress.getByName("255.255.255.255"); //�㲥��ַ sendUdpData(ipmsgSend.getProtocolString() + "\0", broadcastAddr, IpMessageConst.PORT); //�������� } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e(TAG, "noticeOnline()....�㲥��ַ����"); } } public void refreshUsers(){ //ˢ�������û� users.clear(); //��������û��б� noticeOnline(); //��������֪ͨ MyFeiGeBaseActivity.sendEmptyMessage(IpMessageConst.IPMSG_BR_ENTRY); } @Override public void run() { // TODO Auto-generated method stub while(onWork){ try { udpSocket.receive(udpResPacket); } catch (IOException e) { // TODO Auto-generated catch block onWork = false; if(udpResPacket != null){ udpResPacket = null; } if(udpSocket != null){ udpSocket.close(); udpSocket = null; } udpThread = null; Log.e(TAG, "UDP���ݰ�����ʧ�ܣ��߳�ֹͣ"); break; } if(udpResPacket.getLength() == 0){ Log.i(TAG, "�޷�����UDP���ݻ��߽��յ���UDP����Ϊ��"); continue; } String ipmsgStr = ""; try { ipmsgStr = new String(resBuffer, 0, udpResPacket.getLength(),"gbk"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e(TAG, "��������ʱ��ϵͳ��֧��GBK����"); }//��ȡ�յ������� Log.i(TAG, "���յ���UDP��������Ϊ:" + ipmsgStr); IpMessageProtocol ipmsgPro = new IpMessageProtocol(ipmsgStr); // int commandNo = ipmsgPro.getCommandNo(); int commandNo2 = 0x000000FF & commandNo; //��ȡ������ switch(commandNo2){ case IpMessageConst.IPMSG_BR_ENTRY: { //�յ��������ݰ�������û���������IPMSG_ANSENTRYӦ�� addUser(ipmsgPro); //����û� MyFeiGeBaseActivity.sendEmptyMessage(IpMessageConst.IPMSG_BR_ENTRY); //���湹����ͱ������� IpMessageProtocol ipmsgSend = new IpMessageProtocol(); ipmsgSend.setVersion(String.valueOf(IpMessageConst.VERSION)); ipmsgSend.setSenderName(selfName); ipmsgSend.setSenderHost(selfGroup); ipmsgSend.setCommandNo(IpMessageConst.IPMSG_ANSENTRY); //���ͱ������� ipmsgSend.setAdditionalSection(selfName + "\0" ); //������Ϣ������û����ͷ�����Ϣ sendUdpData(ipmsgSend.getProtocolString(), udpResPacket.getAddress(), udpResPacket.getPort()); //�������� } break; case IpMessageConst.IPMSG_ANSENTRY: { //�յ�����Ӧ�𣬸��������û��б� addUser(ipmsgPro); MyFeiGeBaseActivity.sendEmptyMessage(IpMessageConst.IPMSG_ANSENTRY); } break; case IpMessageConst.IPMSG_BR_EXIT:{ //�յ����߹㲥��ɾ��users�ж�Ӧ��ֵ String userIp = udpResPacket.getAddress().getHostAddress(); users.remove(userIp); MyFeiGeBaseActivity.sendEmptyMessage(IpMessageConst.IPMSG_BR_EXIT); Log.i(TAG, "�������߱��ijɹ�ɾ��ipΪ" + userIp + "���û�"); } break; case IpMessageConst.IPMSG_SENDMSG:{ //�յ���Ϣ������ String senderIp = udpResPacket.getAddress().getHostAddress(); //�õ�������IP String senderName = ipmsgPro.getSenderName(); //�õ������ߵ����� String additionStr = ipmsgPro.getAdditionalSection(); //�õ�������Ϣ Date time = new Date(); //�յ���Ϣ��ʱ�� String msgTemp; //ֱ���յ�����Ϣ�����ݼ���ѡ���ж��Ƿ��Ǽ�����Ϣ String msgStr; //���ܺ����Ϣ���� //����������ĸ����ֶε��ж� //���������ִ�����֤ѡ���������յ���Ϣ���� if( (commandNo & IpMessageConst.IPMSG_SENDCHECKOPT) == IpMessageConst.IPMSG_SENDCHECKOPT){ //����ͨ���յ���Ϣ���� IpMessageProtocol ipmsgSend = new IpMessageProtocol(); ipmsgSend.setVersion("" +IpMessageConst.VERSION); //ͨ���յ���Ϣ������ ipmsgSend.setCommandNo(IpMessageConst.IPMSG_RECVMSG); ipmsgSend.setSenderName(selfName); ipmsgSend.setSenderHost(selfGroup); ipmsgSend.setAdditionalSection(ipmsgPro.getPacketNo() + "\0"); //������Ϣ����ȷ���յ��İ��ı�� sendUdpData(ipmsgSend.getProtocolString(), udpResPacket.getAddress(), udpResPacket.getPort()); //�������� } String[] splitStr = additionStr.split("\0"); //ʹ��"\0"�ָ���и����ļ���Ϣ�����ָ���� msgTemp = splitStr[0]; //����Ϣ����ȡ�� //�Ƿ��з����ļ���ѡ��.���У��򸽼���Ϣ���ȡ���������ļ���Ϣ if((commandNo & IpMessageConst.IPMSG_FILEATTACHOPT) == IpMessageConst.IPMSG_FILEATTACHOPT){ //������з����ļ���ش��� Message msg = new Message(); msg.what = (IpMessageConst.IPMSG_SENDMSG | IpMessageConst.IPMSG_FILEATTACHOPT); //�ַ������飬�ֱ���� IP�������ļ���Ϣ,���������ƣ���ID String[] extraMsg = {senderIp, splitStr[1],senderName,ipmsgPro.getPacketNo()}; msg.obj = extraMsg; //�����ļ���Ϣ���� MyFeiGeBaseActivity.sendMessage(msg); break; } //�Ƿ��м���ѡ���ȱ msgStr = msgTemp; // ��ֻ�Ƿ�����Ϣ��������Ϣ ChatMessage msg = new ChatMessage(senderIp, senderName, msgStr, time); if(!receiveMsg(msg)){ //û�����촰�ڶ�Ӧ��activity receiveMsgQueue.add(msg); // ��ӵ���Ϣ���� MyFeiGeBaseActivity.playMsg(); //֮�������ЩUI��ʾ�Ĵ�����sendMessage()�����У���ȱ MyFeiGeBaseActivity.sendEmptyMessage(IpMessageConst.IPMSG_SENDMSG); //����������UI } } break; case IpMessageConst.IPMSG_RELEASEFILES:{ //�ܾ������ļ� MyFeiGeBaseActivity.sendEmptyMessage(IpMessageConst.IPMSG_RELEASEFILES); } break; } //end of switch if(udpResPacket != null){ //ÿ�ν�����UDP���ݺ����ó��ȡ�������ܻᵼ���´��յ����ݰ����ضϡ� udpResPacket.setLength(BUFFERLENGTH); } } if(udpResPacket != null){ udpResPacket = null; } if(udpSocket != null){ udpSocket.close(); udpSocket = null; } udpThread = null; } public boolean connectSocket(){ //�����˿ڣ�����UDP���� boolean result = false; try { if(udpSocket == null){ udpSocket = new DatagramSocket(IpMessageConst.PORT); //�󶨶˿� Log.i(TAG, "connectSocket()....��UDP�˿�" + IpMessageConst.PORT + "�ɹ�"); } if(udpResPacket == null) udpResPacket = new DatagramPacket(resBuffer, BUFFERLENGTH); onWork = true; //���ñ�ʶΪ�̹߳��� startThread(); //�����߳̽���udp���� result = true; } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); disconnectSocket(); Log.e(TAG, "connectSocket()....��UDP�˿�" + IpMessageConst.PORT + "ʧ��"); } return result; } public void disconnectSocket(){ // ֹͣ����UDP���� onWork = false; // �����߳����б�ʶΪ������ stopThread(); } private void stopThread() { //ֹͣ�߳� // TODO Auto-generated method stub if(udpThread != null){ udpThread.interrupt(); //���̶߳��������ж� } Log.i(TAG, "ֹͣ����UDP����"); } private void startThread() { //�����߳� // TODO Auto-generated method stub if(udpThread == null){ udpThread = new Thread(this); udpThread.start(); Log.i(TAG, "���ڼ���UDP����"); } } public synchronized void sendUdpData(String sendStr, InetAddress sendto, int sendPort){ //����UDP���ݰ��ķ��� try { sendBuffer = sendStr.getBytes("gbk"); // ���췢�͵�UDP���ݰ� udpSendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, sendto, sendPort); udpSocket.send(udpSendPacket); //����udp���ݰ� Log.i(TAG, "�ɹ���IPΪ" + sendto.getHostAddress() + "����UDP���ݣ�" + sendStr); udpSendPacket = null; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e(TAG, "sendUdpData(String sendStr, int port)....ϵͳ��֧��GBK����"); } catch (IOException e) { //����UDP���ݰ����� // TODO Auto-generated catch block e.printStackTrace(); udpSendPacket = null; Log.e(TAG, "sendUdpData(String sendStr, int port)....����UDP���ݰ�ʧ��"); } } private synchronized void addUser(IpMessageProtocol ipmsgPro){ //����û���Users��Map�� String userIp = udpResPacket.getAddress().getHostAddress(); User user = new User(); // user.setUserName(ipmsgPro.getSenderName()); user.setAlias(ipmsgPro.getSenderName()); //�����ݶ����������� String extraInfo = ipmsgPro.getAdditionalSection(); String[] userInfo = extraInfo.split("\0"); //�Ը�����Ϣ���зָ�,�õ��û����ͷ����� if(userInfo.length < 1){ user.setUserName(ipmsgPro.getSenderName()); if(userIp.equals(MyFeiGeActivity.hostIp)) user.setGroupName("�Լ�"); else user.setGroupName("�Է�δ�������"); }else if (userInfo.length == 1){ user.setUserName(userInfo[0]); if(userIp.equals(MyFeiGeActivity.hostIp)) user.setGroupName("�Լ�"); else user.setGroupName("�Է�δ�������"); }else{ user.setUserName(userInfo[0]); if(userIp.equals(MyFeiGeActivity.hostIp)) user.setGroupName("�Լ�"); else user.setGroupName(userInfo[1]); } user.setIp(userIp); user.setHostName(ipmsgPro.getSenderHost()); user.setMac(""); //��ʱû������ֶ� users.put(userIp, user); Log.i(TAG, "�ɹ����ipΪ" + userIp + "���û�"); } }