Java学习-Tcp_Socket实现多线程通信

方式一

存在缺点

输入流与输出流在同一个线程内,应该独立处理,彼此独立
读的时候不能写,必须等写完才读

打印结果

111
服务器--》111
222
服务器--》222
333
服务器--》333
44
服务器--》44

服务器端

package com.anqi.tcp2;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(9998);
        Socket socket = server.accept();
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        //先读取后输出
        while(true){
            String str = dis.readUTF();     
            dos.writeUTF("服务器--》"+str);
            dos.flush();
        }

    }

}

客户端

package com.anqi.tcp2;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Client {

    public static void main(String[] args) throws IOException, IOException {
        Socket client = new Socket("localhost",9998);
        //控制台输入流
        BufferedReader console = new BufferedReader(
                new InputStreamReader(System.in));

        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
        while(true){
            String info = console.readLine();
            //输出流
            dos.writeUTF(info);
            dos.flush();
            //输入流
            DataInputStream dis = new DataInputStream(client.getInputStream());
            String str = dis.readUTF();
            System.out.println(str);
        }

    }

}

方式二

打印结果

运行服务器->运行一个客户端 输入a->运行一个客户端 输入 b->
两个客户端均显示
a
b

服务器端

package com.anqi.tcp3;

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<>();
    public static void main(String[] args) throws IOException {
        new Server().start();
    }
    public void start() throws IOException{
        ServerSocket server = new ServerSocket(9998);
        while(true){
                Socket client = server.accept();
                MyChannel channel = new MyChannel(client);
                all.add(channel);//统一管理
                new Thread(channel).start();//一条道路
            }
    }

    /**
     * 一个客户端一条道路
     *  输入流
     *  输入流
     *  接收数据
     *  发送数据
     * @author Angel
     *
     */
    private class MyChannel implements Runnable{
        DataInputStream dis;
        DataOutputStream dos;
        private boolean isRunning = true;
        public MyChannel(Socket client){
            try {
                dis = new DataInputStream(client.getInputStream());
                dos = new DataOutputStream(client.getOutputStream());
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dis,dos);
            }
        }
        /**
         * 读取数据
         * @return
         */
        private String receive(){
            String msg = null;
            try {
                msg = dis.readUTF();
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dis);
                all.remove(this);//移除自身
            }
            return msg;
        }
        /**
         * 发送数据
         */
        private void send(String msg){
            if(msg == null  || msg.equals(""))
                return;
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dos);
                all.remove(this);//移除自身
            }

        }
        /**
         * 发送给其他客户端
         */
        private void sendOthers(){
            String msg = receive();
            //遍历容器
            for (MyChannel others : all) {
                if(others == this)
                    continue;
                //发送给其他客户端
                others.send(msg);
            }

        }
        public void run() {
            while(isRunning){
                sendOthers();
            }

        }
    }
}

客户端

package com.anqi.tcp3;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Client {

    public static void main(String[] args) throws IOException, IOException {
        Socket client = new Socket("localhost",9998);
        //控制台输入流
        new Thread(new Send(client)).start();//一条路径
        new Thread(new Receive(client)).start();//一条路径

    }

}

Send.java

package com.anqi.tcp3;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * 发送数据
 * @author Angel
 *
 */
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) {
            isRunning = false;
            CloseUtil.closeAll(dos,console);
        }
    }
    /**
     * 从控制台接收数据
     * @return
     */
    private String getMsgFromConsole(){
        try {
            return console.readLine();
        } catch (IOException e) {

        }
        return "";
    }
    /**
     * 1.从控制台接收数据
     * 2.发送数据
     */
    public void send(){
        String msg = getMsgFromConsole();
        if(msg != null && !msg.equals("")){
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dos,console);
            }
        }
    }
    public void run() {
            //线程体
            while(isRunning){
                send();
            }
        }
}

Receive.java

package com.anqi.tcp3;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * 接收数据
 * @author Angel
 *
 */
public class Receive implements Runnable{
    //输入流
    private DataInputStream dis;
    //线程控制
    private boolean isRunning = true;
    Receive(){

    }
    Receive(Socket client){
        try {
            dis = new DataInputStream(client.getInputStream());
        } catch (IOException e) {
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
    }
    /**
     * 接收数据
     * @return
     */
    public String receive(){
        String msg = "";
        try {
            msg = dis.readUTF();
        } catch (IOException e) {
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
        return msg;
    }
    public void run() {
        //线程体
        while(isRunning){
            System.out.println(receive());
        }

    }
}

关闭的工具类

package com.anqi.tcp3;

import java.io.Closeable;
import java.io.IOException;

/**
 * 关闭流的方法
 * @author Angel
 *
 */
public class CloseUtil {
    public static void closeAll(Closeable ... io){
        for (Closeable closeable : io) {
            if (closeable != null)
                try
                {
                    closeable.close();
                } catch (IOException e) {}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值