Java TCP协议下聊天室的手工实现

  • Version.1:

        目的:实现单个客户与服务器的连接。

服务器:

import java.io.*;
import java.net.*;
/*
   在线聊天室:服务器
   目的:实现单个客户的聊天过程
 */
public class chat {
    public static void main(String[] args) throws IOException {
        System.out.println("-----Server-----");
        //1、指定端口 使用ServerSocket创建服务器
        ServerSocket server = new ServerSocket(8888);
        //2、阻塞式等待连接 accept()
        Socket client = server.accept();
        System.out.println("一个客户端建立了连接");
        //3、服务器接收消息
        DataInputStream dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
        String str = "null";
        while(!str.equals("")){
            str = dis.readUTF();
            System.out.println(str);
        }
        //3、释放资源
        dis.close();
        server.close();
    }
}

客户端:

import java.io.*;
import java.net.*;
/*
   在线聊天室:客户
   目的:实现单个客户的聊天过程
 */
public class client {
    public static void main(String[] args) throws IOException {
        System.out.println("-----Client-----");
        //1、建立连接:使用Socket创建客户端 + 服务器的地址和端口
        Socket client = new Socket("localhost",8888);
        //2、客户端发送消息
        String str = "null";
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
        while(!str.equals("")){
            str = reader.readLine();
            dos.writeUTF(str);
            dos.flush();
        }
        //3、释放资源
        dos.close();
        client.close();
    }
}
  • Version.2:

        目的:实现多个客户多次、同时收发消息。

服务器:

import SAMPLE.网络编程.TCP协议.聊天室.utils;
import java.io.*;
import java.net.*;
/*
   多人多线程在线聊天室:服务器
   目的:实现多个客户可以多次、同时收发消息
 */
public class multiChat {
    static String[] person = {"","Kvno","Tom","Jerry","Echo","Eric"};
    static int clientNum = 0;
    public static void main(String[] args) throws IOException {
        System.out.println("-----Server-----");
        //1、指定端口 使用ServerSocket创建服务器
        ServerSocket server = new ServerSocket(8888);
        //2、阻塞式等待连接 accept()
        while(clientNum>=0) {
            Socket client = server.accept();
            System.out.println(person[++clientNum]+"进入聊天室");
            new Thread(new Channel(client),person[clientNum]).start();
        }
        server.close();
    }
    static class Channel implements Runnable {
        private DataInputStream dis;
        private DataOutputStream dos;
        private Socket client;
        private boolean flag;
        public Channel(Socket client) {
            this.client = client;
            try {
                dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
                dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
                flag = true;
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("-----2-----");
                close();
            }
        }
        //接收消息
        private String receive()  {
            String str = "null";
            try {
                str = dis.readUTF();
            } catch (IOException e) {
                System.out.println("-----1-----");
                flag = false;
                if(!str.equals("null"))
                    close();
            }
            return str;
        }
        //发送消息
        private void send(String str) {
            try {
                dos.writeUTF(str);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("-----3-----");
                close();
            }
            return ;
        }
        //释放资源
        private void close() {
            this.flag = false;
            System.out.println(Thread.currentThread().getName()+"离开聊天室");
            utils.close(dis,dos,client);
        }
        @Override
        public void run() {
            while(flag) {
                String str = receive();
                if(!str.equals("")&&!str.equals("null")) {
                    System.out.println(Thread.currentThread().getName()+":"+str);
                    send(str);
                }else {
                    flag = false;
                }
            }
            close();
        }
    }
}

客户端:

import SAMPLE.网络编程.TCP协议.聊天室.*;
import java.io.*;
import java.net.*;
/*
   多人多线程在线聊天室:客户端
   目的:实现多个客户可以多次、同时收发消息
 */
public class multiClient {
    public static void main(String[] args) throws IOException {
        System.out.println("-----Client-----");
        //1、建立连接:使用Socket创建客户端 + 服务器的地址和端口
        Socket client = new Socket("localhost",8888);
        //2、客户端发送消息
        new Thread(new Send(client)).start();
        //3、客户端接收消息
        new Thread(new Receive(client)).start();
        //4、释放资源
        //client.close();
    }
}

工具类:

1、封装发送消息:

import java.io.*;
import java.net.*;
/*
   多线程封装发送端
 */
public class Send implements Runnable {
    private Socket client;
    private BufferedReader reader;
    private DataOutputStream dos;
    private boolean flag;
    private String str = "null";
    public Send(Socket client) {
        this.client = client;
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
            flag = true;
        } catch (IOException e) {
            System.out.println("-----4-----");
            close();
        }
    }
    private void send() {
        if(!str.equals("")){
            try {
                str = reader.readLine();
                dos.writeUTF(str);
                dos.flush();
            } catch (IOException e) {
                System.out.println("-----5-----");
                close();
            }
        }else {
            flag = false;
        }
    }
    private void close() {
        this.flag = false;
        utils.close(reader,dos,client);
    }

    @Override
    public void run() {
        while(flag){
            send();
        }
        close();
    }
}

2、封装接收消息:

import java.io.*;
import java.net.*;
/*
   多线程封装接收端
 */
public class Receive implements Runnable {
    private Socket client;
    private DataInputStream dis;
    private boolean flag;
    private String str;
    public Receive(Socket client) {
        this.client = client;
        try {
            dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
            flag = true;
        } catch (IOException e) {
            System.out.println("-----6-----");
            close();
        }
    }
    private void receive() {
        String str = null;
        try {
            str = dis.readUTF();
            if(!str.equals("")){
                System.out.println(str);
            }else {
                flag = false;
            }
        } catch (IOException e) {
            flag = false;
            close();
        }
    }
    private void close() {
        this.flag = false;
        utils.close(dis,client);
    }
    @Override
    public void run() {
        while(flag){
            receive();
        }
        close();
    }
}

3、封装释放资源:

import java.io.*;
/*
   释放资源
 */
public class utils {
    public static void close(Closeable... io){
        for(Closeable i:io){
            if (i!= null) {
                try {
                    i.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • Version.3:

        目的:实现多个客户可以多次、同时针对群体、私人收发消息。引用了Version.2中的封装方法。

服务器:

import SAMPLE.网络编程.TCP协议.聊天室.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.CopyOnWriteArrayList;
/*
   多人多线程在线聊天室:服务器
   目的:实现多个客户可以多次、同时收发消息
        实现群发、私发消息
 */
public class theChat {
    private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<>();
    private static String[] person = {"","Kvno","Tom","Jerry","Echo","Eric"};
    private static int clientNum = 0;
    public static void main(String[] args) throws IOException {
        System.out.println("-----Server-----");
        //1、指定端口 使用ServerSocket创建服务器
        ServerSocket server = new ServerSocket(8888);
        //2、阻塞式等待连接 accept()
        while(clientNum>=0) {
            Socket client = server.accept();
            System.out.println(person[++clientNum]+"进入聊天室");
            Channel c = new Channel(client);
            all.add(c);
            new Thread(c,person[clientNum]).start();
        }
        server.close();
    }
    static class Channel implements Runnable {
        private DataInputStream dis;
        private DataOutputStream dos;
        private Socket client;
        private boolean flag;
        public Channel(Socket client) {
            this.client = client;
            try {
                dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
                dos = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
                flag = true;
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("-----2-----");
                close();
            }
        }
        //接收消息
        private String receive()  {
            String str = "null";
            try {
                str = dis.readUTF();
            } catch (IOException e) {
                System.out.println("-----1-----");
                flag = false;
                if(!str.equals("null"))
                    close();
            }
            return str;
        }
        //发送消息
        private void send(String str) {
            try {
                dos.writeUTF(str);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("-----3-----");
                close();
            }
            return ;
        }
        //群发/私发消息
        private void groupSend(String str) {
            if(str.startsWith("@")) {
                int idx = str.indexOf(':');
                String name = str.substring(1,idx);
                String msg = str.substring(idx+1);
                for(int i=0;i<5;i++) {
                    if(person[i+1].equals(name))
                        all.get(i).send(Thread.currentThread().getName()+"悄悄对你说:"+msg);
                }
            }else {
                for (Channel others : all) {
                    if (others != this)
                        others.send(Thread.currentThread().getName() + ":" + str);
                }
            }
            return ;
        }
        //释放资源
        private void close() {
            this.flag = false;
            System.out.println(Thread.currentThread().getName()+"离开聊天室");
            utils.close(dis,dos,client);
            all.remove(this);
        }

        @Override
        public void run() {
            while(flag) {
                String str = receive();
                if(!str.equals("")&&!str.equals("null")) {
                    if(!str.startsWith("@"))
                        System.out.println(Thread.currentThread().getName()+":"+str);
                    groupSend(str);
                }else {
                    flag = false;
                }
            }
            close();
        }
    }
}

客户端:

import SAMPLE.网络编程.TCP协议.聊天室.*;
import java.io.IOException;
import java.net.Socket;
/*
   多人多线程在线聊天室:客户端
   目的:实现多个客户可以多次、同时收发消息
        实现群发、私发消息
 */
public class theClient {
    public static void main(String[] args) throws IOException {
        System.out.println("-----Client-----");
        //1、建立连接:使用Socket创建客户端 + 服务器的地址和端口
        Socket client = new Socket("localhost",8888);
        //2、客户端发送消息
        new Thread(new Send(client)).start();
        //3、客户端接收消息
        new Thread(new Receive(client)).start();
        //4、释放资源
        //client.close();
    }
}

至此,我们简单实现了TCP协议下的聊天室。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值