网络编程_TCP_Socket通信_聊天室_客户端多线程_群聊JAVA191-192

来源:http://www.bjsxt.com/
一、S02E191_01网络编程TCP_Socket通信聊天室_客户端多线程
二、S02E192_01网络编程TCP_Socket通信聊天室_群聊

package com.test.net.tcp.chat;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 创建客户端:发送数据+接收数据
 * 写出数据:输出流
 * 读取数据:输入流
 * 
 * 输入流与输出流应该独立处理,彼此独立,在不同的线程中
 */
public class Client {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket client = new Socket("LWT-PC",9999);
        //控制台输入流
        new Thread(new Send(client)).start();//一条路径
        new Thread(new Receive(client)).start();//一条路径
    }
}
package com.test.net.tcp.chat;

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.List;
/**
 * 创建服务器
 * 写出数据:输出流
 * 读取数据:输入流
 */
public class Server {
    private List<MyChannel> all = new ArrayList<MyChannel>();

    public static void main(String[] args) throws IOException {
        new Server().start();
    }

    public void start() throws IOException{
        ServerSocket server = new ServerSocket(9999);
        while(true){
            Socket client = server.accept();
            MyChannel channel = new MyChannel(client);
            all.add(channel);//统一管理
            new Thread(channel).start();//一条道路
        }
    }
    /**
     * 一个客户端一条道路
     * 1、输入流
     * 2、输出流
     * 3、接收数据
     * 4、发送数据
     */
    private class MyChannel implements Runnable{
        private DataInputStream dis;
        private DataOutputStream dos;
        private boolean isRunning = true;

        public MyChannel(Socket client) {
            try {
                dis = new DataInputStream(client.getInputStream());
                dos = new DataOutputStream(client.getOutputStream());
            } catch (IOException e) {
                //e.printStackTrace();
                CloseUtil.closeAll(dis,dos);
                isRunning = false;
            }
        }
        /**
         * 读取数据
         * @return
         */
        private String receive(){
            String msg = "";
            try {
                msg = dis.readUTF();
            } catch (IOException e) {
                //e.printStackTrace();
                CloseUtil.closeAll(dis);
                isRunning = false;
                all.remove(this);//移除自身
            }
            return msg;
        }
        /**
         * 发送数据
         */
        private void send(String msg){
            if(null==msg || msg.equals("")){
                return;
            }
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                //e.printStackTrace();
                CloseUtil.closeAll(dos);
                isRunning = false;
                all.remove(this);//移除自身
            }
        }
        /**
         * 发送给其它客户端
         */
        private void sendOthers(){
            String msg = this.receive();
            //遍历容器
            for (MyChannel other : all) {
                if(other==this){
                    continue;
                }
                //发送给其它客户端
                other.send(msg);
            }
        }

        @Override
        public void run() {
            while(isRunning){
                sendOthers();
            }
        }
    }
}
package com.test.net.tcp.chat;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
 * 发送数据线程
 */
public class Send implements Runnable{
    //控制台输入流
    private BufferedReader console;
    //管道输出流
    private DataOutputStream dos;
    //控制线程
    private boolean isRunning = true;

    public Send() {
        console = new BufferedReader(new InputStreamReader(System.in));
    }
    public Send(Socket client) {
        this();
        try {
            dos = new DataOutputStream(client.getOutputStream());
        } catch (IOException e) {
            //e.printStackTrace();
            isRunning = false;
            CloseUtil.closeAll(dos,console);
        }
    }
    //1、从控制台接收数据
    private String getMsgFromConsole(){
        try {
            return console.readLine();
        } catch (IOException e) {
            //e.printStackTrace();
        }
        return "";
    }
    /**
     * 1、从控制台接收数据
     * 2、发送数据
     */
    public void send(){
        String msg = getMsgFromConsole();
        if(null!=msg && !msg.equals("")){
            try {
                dos.writeUTF(msg);
                dos.flush();//强制刷新
            } catch (IOException e) {
                //e.printStackTrace();
                isRunning = false;
                CloseUtil.closeAll(dos,console);
            }
        }
    }

    @Override
    public void run() {
        while(isRunning){
            send();
        }
    }
}
package com.test.net.tcp.chat;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
 * 接收数据线程
 */
public class Receive implements Runnable {
    //输入流
    private DataInputStream dis;
    //线程标识
    private boolean isRunning = true;

    public Receive() {
    }
    public Receive(Socket client){
        try {
            dis = new DataInputStream(client.getInputStream());
        } catch (IOException e) {
            //e.printStackTrace();
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
    }
    /**
     * 接收数据
     */
    public String receive(){
        String msg = "";
        try {
            msg = dis.readUTF();
        } catch (IOException e) {
            //e.printStackTrace();
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
        return msg;
    }
    @Override
    public void run() {
        while(isRunning){
            System.out.println(receive());
        }
    }
}
package com.test.net.tcp.chat;

import java.io.Closeable;
import java.io.IOException;
/**
 * 关闭流的方法
 */
public class CloseUtil {
    public static void closeAll(Closeable...io){
        for (Closeable temp : io) {
            if(null!=temp){
                try {
                    temp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值