ym——Android从零开始(27)(山寨版微信-上)(新)

转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!


山寨版微信(上)

即时通信

我们使用了Socket编程(套接字编程)

服务器

创建ServerSocket

等待客户端的连接

Socket s =ss.qccpet();

客户端

Soket s = new Socket();

原理图:

1.png

服务端:
Server

public class Server {
    // 记录所有的客户端
    private List<ThreadClient> list = new ArrayList<ThreadClient>();
    // 启动服务器
    public void start() throws Exception {
        // 创建一个服务器
        final ServerSocket serverSocket = new ServerSocket(8809);
        System.out.println(serverSocket.getLocalPort());
System.out.println(serverSocket.getInetAddress().getHostAddress());
        // 开线程去反馈给用户的信息
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 开启循环接受客服端反馈的信息
                while (true) {
                    try {
                        // 得到客户端反馈的信息
                        Socket socket =serverSocket.accept();
                        // 取出客户的信息
                        ThreadClient client = new ThreadClient(socket);
                        System.out.println("ip:"+client.ip+",port:"+client.port);
                        
                        /**自定义通信协议
                         * 服务器通知用户刷新列表,
                         * 用户上线 refresh:
                         * 关键字 name:上线的ip地址
                         * port:上线的端口
                         * refresh@name@port
                         */
                        // 告诉别人我上线了
                        // 通知之前上线的人
                        /**
                         *  迭代所有客户端:发送消息给每一个客户端
                         *  c:之前上线的用户(别人)
                         */
                        for (ThreadClient c : list) {
                            String msg = "refresh@" +client.ip+ "@" +client.port;
                            c.sendMessge(msg);
                        }
                        // 上线后得到上线的人
                        // 自己上线之后,也要知道之前上线的人
                        for (ThreadClient c : list) {
                            String msg = "refresh@" +c.ip+ "@" +c.port;
                            client.sendMessge(msg);
                        }
                        
                        list.add(client);
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
            }
        }).start();
    }
    public static void main(String[] args) {
        Server server = new Server();
        try {
            server.start();
        } catch (Exception e) {
            // TODO Auto-generated catchblock
            e.printStackTrace();
            System.out.println("启动失败");
        }
        
    }
}

ThreadClient

Socket详细信息

// 用户相信信息
public class ThreadClient extends Thread {
    // ip 地址
    public String ip;
    // 端口号
    public int port;
    // 客户端套接字
    public Socket socket;
    // 字节输入流
    public InputStream is;
    // 字节输出流
    public OutputStream os;
    // 字符打印流
    public PrintWriter pw;
    // 字符缓存流
    public BufferedReader br;
   
    public ThreadClient(Socketsocket){
        try {
            this.socket = socket;
            this.port = socket.getPort();
            this.ip =socket.getInetAddress().getHostAddress();
            this.is = socket.getInputStream();
            this.os =socket.getOutputStream();
            this.br = new BufferedReader(new InputStreamReader(is));
            this.pw = new PrintWriter(os);
            
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
    // 向客户端发送消息的方法
    public void sendMessge(String msg)
    {
        pw.println(msg);
        pw.flush();
    }   @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
    }
}

客户端:

2.png

Adapter

public class MyAdapter extends BaseAdapter {
    private List<UserInfo> infos;
    private Context context;
    private LayoutInflater mInflater;
    publicMyAdapter(List<UserInfo> infos,Context context){
            this.infos = infos;
            this.context = context;
            mInflater = LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return infos.size();
    }
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return infos.get(position);
    }
    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        View view = null;
        ViewHodler hodler = null;
        if(convertView!=null){
            view = convertView;
            hodler = (ViewHodler) view.getTag();
            
        }else
        {
            view = mInflater.inflate(R.layout.item, null);
            hodler = new ViewHodler();
            hodler.tv_ip = (TextView) view.findViewById(R.id.tv_ip);
        hodler.tv_port = (TextView)view.findViewById(R.id.tv_port);
    hodler.tv_isnew = (TextView) view.findViewById(R.id.tv_isnew);
            view.setTag(hodler);
        }
        // 得到数据
        UserInfo info = infos.get(position);
        hodler.tv_ip.setText(info.ip);
        hodler.tv_port.setText(info.port+"");
        
        return view;
    }
    private class ViewHodler{
        TextView tv_ip;
        TextView tv_port;
        TextView tv_isnew;
    }
}

Client

public class ThreadClient extends Thread {
    public List<UserInfo> userInfos= new ArrayList<UserInfo>();
    public Socket socket;
    public String ip;
    public int port;
    public InputStream is;
    public OutputStream os;
    public PrintWriter pw;
    public BufferedReader br;
    public static Context context;
    private static ThreadClient threadClient;
    public synchronized static ThreadClient  getThreadClient(Context c){
        context = c;
        if(threadClient == null){
            try {
                //创建Socket
                Socket socket = new Socket("192.168.16.2", 8809);
                threadClient = new ThreadClient(socket);
                threadClient.start();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
        return threadClient;
    }
    private ThreadClient(Socketsocket){
        this.socket = socket;
        this.ip = socket.getInetAddress().getHostAddress();
        this.port = socket.getPort();
        try {
            this.is = socket.getInputStream();
            this.os =socket.getOutputStream();
            this.pw = new PrintWriter(os);
            this.br = new BufferedReader(new InputStreamReader(is));
        } catch (Exception e) {
            
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
         
        super.run();
        while(true){
            try {
                String message = br.readLine();
                if(message!=null)
                {
//StringTokenizer 用户截取有规律符号的字符串的
            StringTokenizer token = new StringTokenizer(message,"@");
                    String msg = token.nextToken();
                    // 判断是否是上线通知
                    if("refresh".equals(msg))
                    {
                        String ip1 =token.nextToken();
                int port1 = Integer.parseInt(token.nextToken());
                        // 发送广播刷新列表
如果不是自己上线就发送广播刷新用户列表
             boolean flag = this.ip.equals(ip1)&&this.port == port1;
                         if(!flag){
                             userInfos.add(new UserInfo(ip1, port1));
                             Intent intent = new Intent();
                             intent.setAction("com.cym.MainActivity");
                             context.sendBroadcast(intent);
                         }
                    }
                }
               
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
        
    }
}

Domain

public class UserInfo {
    public String ip;
    public int port;
    public boolean isNew;
    public UserInfo(String ip, int port) {
        super();
        this.ip = ip;
        this.port = port;
    }
   
}

Ui

public class MainActivity extends Activity {
    private ListView lv_user;
    private MyAdapter adapter;
    private MyRefreshBroadCastReceiverreceiver;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lv_user = (ListView) findViewById(R.id.lv_user);
        // 客户端
     ThreadClient threadClient = ThreadClient.getThreadClient(this);
      
        List<UserInfo> userInfos =threadClient.userInfos;
        adapter = new MyAdapter(userInfos, this);
        lv_user.setAdapter(adapter);
        
        receiver = new MyRefreshBroadCastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.cym.MainActivity");
        registerReceiver(receiver, filter);
        
    }
private class MyRefreshBroadCastReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context,Intent intent) {
            // TODO Auto-generated methodstub
            adapter.notifyDataSetChanged();
        }
        
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值