ym——Android从零开始(27)(山寨版微信-上)(新)
来源:互联网 发布:社会发展统计数据库 编辑:程序博客网 时间:2024/05/29 03:44
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!
山寨版微信(上)
即时通信
我们使用了Socket编程(套接字编程)
服务器
创建ServerSocket
等待客户端的连接
Socket s =ss.qccpet();
客户端
Soket s = new Socket();
原理图:
服务端: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(); }}客户端: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(); } }}
0 0
- ym——Android从零开始(27)(山寨版微信-上)(新)
- ym——Android从零开始(27)(山寨版微信-下)(新)
- ym——Android从零开始(17)(多线程下载-上)(新)
- ym——Android从零开始(7)(SQLite数据库)(新)
- ym——Android从零开始(9)(ContentProvider内容提供者)(新)
- ym——Android从零开始(18)(多线程下载-下)(新)
- ym——Android从零开始(20)(TabHost+ExpandableListView)(新)
- ym——Android从零开始(21)(自定义控件)(新)
- ym——Android从零开始(19)(BroadcastReceiver)(新)
- ym——Android从零开始(22)(service、aidl)(新)
- ym——Android从零开始(23)(Notification+ Animation)(新)
- ym——Android从零开始(24)(多媒体播放器)(新)
- ym——Android从零开始(29)(Bluetooth2.0+4.0)(新)
- ym——Android从零开始(30)(WIFI、传感器)(新)
- ym——Android从零开始(31)(AppWidget、快捷图标)(新)
- ym——Android从零开始(32)(WebView)(新)
- ym——Android从零开始(1)(Android体系架构及认识)(新)
- ym——Android从零开始(2)(打电话,发短信,常用布局)(新)
- mybatis中的#{}跟${}的区别
- ym——Android从零开始(26)(设置全屏+横屏、相机拍照、视频录制)(新)
- POJ - 2442 Sequence
- Class类和反射
- ora-01555,ORA-22924解决
- ym——Android从零开始(27)(山寨版微信-上)(新)
- How to write software Testing Weekly Status Report
- bzoj 3173 最长上升子序列
- SQL Server死锁总结
- 使用dos 写bat时,使用for循环读取文件中的内容无任何显示
- MySQL CURDATE() 函数
- ym——Android从零开始(27)(山寨版微信-下)(新)
- jQuery Mobile 特性
- 线程安全及不可变性