Android 基于Socket的聊天室(一)

来源:互联网 发布:自学java不学c语言 编辑:程序博客网 时间:2024/06/16 00:00

Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。

 

Client A  发信息给 Client B ,  A的信息首先发送信息到服务器Server ,Server接受到信息后再把A的信息广播发送给所有的Clients

首先我们要在服务器建立一个ServerSocket ,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状态。

Socket accept():如果接收到一个客户端Socket的连接请求,该方法将返回一个与客户端Socket对应的Socket

Server示例:

复制代码
//创建一个ServerSocket,用于监听客户端Socket的连接请求ServerSocket ss = new ServerSocket(30000);//采用循环不断接受来自客户端的请求while (true){//每当接受到客户端Socket的请求,服务器端也对应产生一个SocketSocket s = ss.accept();//下面就可以使用Socket进行通信了...}
复制代码

 

客户端通常可使用Socket的构造器来连接到指定服务器
Client示例:

//创建连接到服务器、30000端口的SocketSocket s = new Socket("192.168.2.214" , 30000);//下面就可以使用Socket进行通信了...


这样Server和Client就可以进行一个简单的通信了
当然,我们要做的是多客户,所以每当客户端Socket连接到该ServerSocket之后,程序将对应Socket加入clients集合中保存,并为该Socket启动一条线程,该线程负责处理该Socket所有的通信任务

//定义保存所有Socket的ArrayListpublic static ArrayList<Socket> clients = new ArrayList<Socket>();

当服务器线程读到客户端数据之后,程序遍历clients集合,并将该数据向clients集合中的每个Socket发送一次。这样就可以实现一个聊天室的功能了

 

 

下面来看看整个功能的demo

先建立一个Java工程,把Server.java运行起来,然后再运行手机模拟器

 

    

服务器打印信息:

 

程序文件结构:


嘿嘿,大家别笑我,我的JAVA水平还是初学者,很多地方都觉得很菜,代码规格程度:小学。 有待提高啊!

 

1.先看看主Activity : SocketmsgActivity.java

SocketmsgActivity.java

 

2.初始化IP和端口Activity, IniActivity.java

IniActivity.java

 

3.初始化用户名称Activity, IniuserActivity.java

IniuserActivity.java

 

4.config.java

config.java

 

布局文件:

1.main.xml

main.xml


2.config.xml

config.xml

3.configuer.xml

configuser.xml

 

style文件:dimens.xml

dimens.xml

 

最后是服务器文件:Server.java

复制代码
  1 import java.io.*;  2 import java.net.*;  3 import java.text.DateFormat;  4 import java.text.SimpleDateFormat;  5 import java.util.*;  6   7 import javax.sound.sampled.Port;  8 import javax.swing.JOptionPane;  9  10 public class Server { 11      12     ServerSocket ss = null; 13     private String getnameString=null; 14     boolean started = false; 15     List<Client> clients = new ArrayList<Client>(); 16     List<Info> infos = new ArrayList<Info>(); 17     public static void main(String[] args) { 18         String inputport = JOptionPane.showInputDialog("請輸入該服務器使用的端口:"); 19         int port = Integer.parseInt(inputport); 20         new Server().start(port); 21     } 22   23     public void start(int port) { 24         try { 25            ss = new ServerSocket(port); 26            System.out.println("服務器啟動"); 27            started = true; 28         } catch (BindException e) { 29               System.out.println(" 端口已经被占用"); 30               System.exit(0); 31            } 32           catch (IOException e) { 33              e.printStackTrace(); 34           } 35  36       try { 37          while (started) { 38              Socket s = ss.accept(); 39              Client c = new Client (s); 40              System.out.println("a client is connected"); 41              new Thread(c).start(); 42              clients.add(c); 43               44               45          } 46       } catch (IOException e) { 47             e.printStackTrace(); 48          } 49          finally { 50             try { 51                ss.close(); 52             } catch (IOException e) { 53                   e.printStackTrace(); 54                } 55          } 56    } 57    public List<Client> getClient(){ 58        return clients; 59    } 60  61   class Client implements Runnable { 62      private String chatKey="SLEEKNETGEOCK4stsjeS"; 63      private Socket s = null; 64      private DataInputStream dis = null; 65      private DataOutputStream dos = null; 66      private boolean bConnected = false; 67      private String sendmsg=null; 68      Client (Socket s) { 69         this.s = s; 70         try { 71           dis = new DataInputStream (s.getInputStream()); 72           dos = new DataOutputStream (s.getOutputStream()); 73           bConnected = true; 74         } catch(IOException e) { 75               e.printStackTrace(); 76            } 77      } 78       79      public void send (String str) { 80           81          try { 82              //System.out.println(s); 83              dos.writeUTF(str+""); 84              dos.flush(); 85          } catch(IOException e) { 86              clients.remove(this); 87              System.out.println("对方已经退出了"); 88          } 89      } 90      public void run() { 91          try { 92             while (bConnected) { 93                 String str = dis.readUTF(); 94                 DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 95                 String date = "  ["+df.format(new Date())+"]"; 96                 if(str.startsWith(chatKey+"online:")){ 97                     Info info = new Info(); 98                     getnameString = str.substring(27); 99                     100                     info.setName(getnameString);101                     infos.add(info);102                     for (int i=0; i<clients.size(); i++) {103                       Client c = clients.get(i);104                       c.send(getnameString+" on line."+date);105                     }106                     System.out.println(getnameString+" on line."+date);107                 }else if(str.startsWith(chatKey+"offline:")){108                     getnameString = str.substring(28);109                     clients.remove(this);110                     for (int i=0; i<clients.size(); i++) {111                           Client c = clients.get(i);112                           c.send(getnameString+" off line."+date);113                         }114                     System.out.println(getnameString+" off line."+date);115                 }116                 else{117                     int charend = str.indexOf("end;");118                     String chatString = str.substring(charend+4);119                     String chatName = str.substring(25, charend);120                     121                     sendmsg=chatName+date+"\n"+chatString; 122                     for (int i=0; i<clients.size(); i++) {123                         Client c = clients.get(i);124                         c.send(sendmsg);125                       }126                     System.out.println(sendmsg);127                 }128              }129          } catch (SocketException e) {130              System.out.println("client is closed!");131              clients.remove(this);132          } catch (EOFException e) {133                System.out.println("client is closed!");134                clients.remove(this);135             }136             catch (IOException e) {137                e.printStackTrace();138             }139            finally {140              try {141                if (dis != null) dis.close();142                if (dos != null) dos.close();143                if (s != null) s.close();144              } catch (IOException e) {145                    e.printStackTrace();146                }147            }148      }149   }150   151   class Info{152       private String info_name = null;153       public Info(){154           155       }156       public void setName(String name){157           info_name = name;158       }159       public String getName(){160           return info_name;161       }162   }163 }
复制代码

 

以上只是一个粗略的聊天室功能,如果要实现私聊,还需要保存该Socket关联的客户信息。一个客户端可以将信息发送另一个指定客户端。实际上,我们知道所有客户端只与服务器连接,客户端之间并没有互相连接。这个功能等我以后有时间再写个demo.....


原文链接:http://www.cnblogs.com/-run/archive/2011/12/29/2306363.html
可以在原文中查看代码
0 0
原创粉丝点击