前言

这是我用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 ListView没有数据时信息显示
  2. Android(安卓)SQLite数据库操作实例
  3. Android开发中RxJava-SQLBrite实时刷新UI
  4. 【Android(安卓)初学】10、Intent对象的使用
  5. Android(安卓)内存数据库
  6. android 使用Intent传递数据之剪切板
  7. Android的SDK与ADT不匹配问题
  8. android笔记
  9. android 使用Intent传递数据之剪切板

随机推荐

  1. Android adb shell 启动java程序
  2. as gradle debug\values\generated.xml
  3. Android接口测试-JUnit入门
  4. 从J2EE转向Android的第六天-----文件管理
  5. Android 系统图标
  6. Android(安卓)OTA 升级之一:编译升级包
  7. Android wifi的WifiInfo对象详解
  8. H5与原生IOS交互
  9. android httpclient 上传文件
  10. Android P Launcher APP替换图标不随系统