前言

这是我用java写的Android聊天室项目的服务端,当然也可用于java项目。这里写了两个服务端,一个只实现多人聊天,一个可多人,可一对一。

Android客户端
源码

  • 服务端1(多人聊天)
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.HashMap;public class Run2 {    private final static int PORT = 12345;//自定义端口号    public static ArrayList<Socket> list ;    public static void main(String[] args) throws IOException {    //重开一条线程启动服务器        new Thread(new startServer()).start();    }    static class startServer implements Runnable{        @Override        public void run() {            try {                ServerSocket server = new ServerSocket(PORT);                        list = new ArrayList<>();                while (true) {                    Socket client = server.accept();                    System.out.println(client);                    //只要有人连接上就把对应的Socket就存入List集合中                    list.add(client);                    //再开一条线程用来传输数据                    //调用构造器,第一个参数是当前的Socket,根据他去获取用户传入的数据                    //第二个参数是List集合,通过他去给每个连接上的发送数据                    new choicesend2(client,list).start();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}class choicesend2 extends Thread {    private Socket socket;    private DataOutputStream dos;     private DataInputStream dis;    public ArrayList<Socket> list;    public choicesend2(Socket socket, ArrayList<Socket> list) {        this.socket = socket;        this.list = list;    }    @Override    public void run() {        try {        //            dis = new DataInputStream(socket.getInputStream());            //这里一定要无限循环,不然只能接收一次消息            while (true) {//使服务器无限循环                        //这些都是用来接收用户传来的数据的,可自行更改                String title;                String name;                String ip;                char[] temp = new char[200];                int len = 0;                char c = 0;                while ((c = dis.readChar()) != '\t') {                    temp[len] = c;                    len++;                }                title = new String(temp, 0, len);                len = 0;                while ((c = dis.readChar()) != '\t') {                    temp[len] = c;                    len++;                }                name = new String(temp, 0, len);                len = 0;                while ((c = dis.readChar()) != '\t') {                    temp[len] = c;                    len++;                }                ip = new String(temp, 0, len);                System.out.println(ip);                                //遍历集合,拿出每一个连接的Socket,向他们发送数据                for (Socket socket : list) {                    if(socket==this.socket)         //如果是自己就不发                        continue;                     // 让dos关联每一个Socket,吧数据传出                      dos = new DataOutputStream(socket.getOutputStream());                    try {                        dos.writeChars(title);                        dos.writeChar('\t');                        dos.writeChars(name);                        dos.writeChar('\t');                        dos.writeInt(0);                        dos.flush();                    } catch (IOException e) {                        e.printStackTrace();                    }                }            }        }catch (IOException e) {            e.printStackTrace();        }    }}
  • 服务端2(多人聊天+一对一)
问题:我们在多人聊天时是用ArrayList集合来存放每一个连接上的Socket对象,但是显然我们自己无法判断出那个是我要去传输数据的Socket
解决方案:把ArrayList改为HashMap,键存放识别用户的信息,值存放Socket,发送时根据键判断是否要与此时的Socket建立连接
比如我的键传的ip,根据ip判断是否建立连接(显然这种不能在一台电脑上相互传输,(HashMap无重复))
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.HashMap;public class Run {    private final static int PORT = 12345;    public static ArrayList<Socket> list ;    public static HashMap<String,Socket> hs;    public static void main(String[] args) throws IOException {        new Thread(new startServer()).start();    }    static class startServer implements Runnable{        @Override        public void run() {            try {                ServerSocket server = new ServerSocket(PORT);                hs = new HashMap<>();                while (true) {                    Socket client = server.accept();                    System.out.println(client);                    hs.put(client.getInetAddress().toString(),client);                    new choicesend(client,hs).start();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}class choicesend extends Thread {    private Socket socket;    private String key;    private DataOutputStream dos;    private DataInputStream dis;    public HashMap<String,Socket> hs;    public choicesend(Socket socket, HashMap<String,Socket> hs) {        this.socket = socket;        this.hs = hs;    }    @Override    public void run() {        try {            dis = new DataInputStream(socket.getInputStream());            while (true) {//使服务器无限循环                String title;                String name;                //这里是我传入的ip,与HashMap进行匹配                String ip;                char[] temp = new char[200];                int len = 0;                char c = 0;                while ((c = dis.readChar()) != '\t') {                    temp[len] = c;                    len++;                }                title = new String(temp, 0, len);                len = 0;                while ((c = dis.readChar()) != '\t') {                    temp[len] = c;                    len++;                }                name = new String(temp, 0, len);                len = 0;                while ((c = dis.readChar()) != '\t') {                    temp[len] = c;                    len++;                }                ip = new String(temp, 0, len);                System.out.println(ip);                //如果传入的是255.255.255.255说明是群发                if(ip.equals("255.255.255.255")){                    for(String sendip : hs.keySet()){                        System.out.println(sendip+"集合中的ip");                        Socket socket = hs.get(sendip);                        dos = new DataOutputStream(socket.getOutputStream());                        try {                           // System.out.println("我发了");                            dos.writeChars(title);                            dos.writeChar('\t');                            dos.writeChars(name);                            dos.writeChar('\t');                            dos.writeInt(0);                            dos.flush();                        } catch (IOException e) {                            //list.remove(socket);                            e.printStackTrace();                        }                    }                }                //否则用传入的ip与HashMap的键匹配                else{                    for(String sendip : hs.keySet()){                       // System.out.println(sendip+"集合中的ip");                       //刚才通过client.getInetAddress().toString()获取的ip开头是“/”,所以去掉第一位                        sendip = sendip.substring(1,sendip.length());                        //如果匹配上拿到对应的Socket对象                        if(ip.equals(sendip)){                            Socket socket = hs.get(sendip);                            if(socket!=null)                                dos = new DataOutputStream(socket.getOutputStream());                            try {                                System.out.println("我发了");                                dos.writeChars(title);                                dos.writeChar('\t');                                dos.writeChars(name);                                dos.writeChar('\t');                                dos.writeInt(1);                                dos.flush();                            } catch (IOException e) {                               // list.remove(socket);                                e.printStackTrace();                            }                        }                    }                }            }        }catch (IOException e) {            e.printStackTrace();        }    }}

反思:

这种一对一的局限性显然很大,只能通过ip去匹配,如果想通过id去找人又如何匹配呢?我认为可以写一个注册登录界面,当登录时就可以获取到用户的Socket,用HashMap去维护,键传入id,值传入Socket对象,这样只要是登录的都传进了我们的HashMap,当需要一对一时就可以用id去匹配聊天。

更多相关文章

  1. Android SQLite数据库操作实例
  2. 【Android】Android 联系人数据库浅析之通话记录
  3. android与服务端通信
  4. android 使用Intent传递数据之剪切板
  5. Android 内存数据库
  6. android入门1:有关布局与activity数据传递等
  7. Android联系人数据库全解析(5)
  8. android 5.0多用户支持

随机推荐

  1. 把excel表格里的数据导入sql数据库的两种
  2. 查询存储过程中特定字符的方法
  3. 如何优化SQL语句的心得浅谈
  4. SQL Server 比较日期大小的方法
  5. 在SQL Server中使用命令调用SSIS包的具体
  6. sql中设置联合主键的具体方法
  7. SQL进行排序、分组、统计的10个新技巧分
  8. insert into select和select into的使用
  9. sql server的一个有趣的bit位运算分享
  10. SQL实现递归及存储过程中In()参数传递解