聊天室服务端

前言

这是我用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去匹配聊天。

猜你喜欢

转载自blog.csdn.net/haazzz/article/details/107751187
今日推荐