java 网络编程-TCP-多人群聊究极版

客户端:
多个客户可以正常收发信息,因为可以同时发送和接受信息,不是发送完信息后等待
返回信息,所以要加入多线程

 public class Client {

public static void main(String[]args) throws UnknownHostException, IOException
{
    System.out.println("客户端启动中...");
    BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
    System.out.println("请输入用户名:");
    String name=br.readLine();
    Socket client =new Socket("localhost",9999);

    new Thread(new Send(client,name)).start();//在线程还没启动之前,通过构造方法发送名称,先于信息的发送,
    //因为接收信息时,名称已经发送并被读取到变量中

    new Thread(new Receive(client)).start();

}
}

作为释放资源工具类

public class utils {

public static void close(Closeable... target )
{
    for(Closeable it:target)
    {
            try {
                if(null!=it)
                {
                it.close();
                }
            } catch (IOException e) {

                e.printStackTrace();
            }

    }
}
}

客户端的发送端封装了:
发送消息
从键盘读取消息
run()
释放资源

 public class Send implements Runnable{

private BufferedReader br;
private DataOutputStream dos;
private Socket client;
private boolean flag=true;
private String name;

public Send(Socket client,String name)
{
    this.client=client;
    this.name=name;
    br=new BufferedReader(new InputStreamReader(System.in));
    try {
        dos=new DataOutputStream(client.getOutputStream());
        //发送名称
        send(name);
    } catch (IOException e) {

        this.release();
    }
}
public void run()
{
    while(flag)
    {
        String msg=getstr();
        send(msg);

    }
}
private void release()
{
    this.flag=false;
    utils.close(dos,client);
}
//从控制台获取消息
private String getstr()
{
    try {
        String msg=br.readLine();
        return msg;
    } catch (IOException e) {

        e.printStackTrace();
    }
    return null;
}
private void send(String msg)
{
    try {
        dos.writeUTF(msg);
        dos.flush();

    } catch (IOException e) {
    release();
    }
}
}

客户端的接收端封装了:
接收消息
run()
释放资源

 public class Receive implements Runnable {
private DataInputStream dis;
private Socket client;
private boolean flag=true;

public Receive(Socket client)
{
    this.client=client;
    try {
        dis=new DataInputStream(client.getInputStream());
    } catch (IOException e) {
        release();
    }
}

private String receive()
{
    String msg;
    try {
        msg = dis.readUTF();
        return msg;
    } catch (IOException e) {
        release();
    }
    return null;
}
public void run()
{
    while(flag)
    {
        String msg=receive();
        System.out.println(msg);
    }

}
private void release()
{
    this.flag=false;
    utils.close(dis,client);
}
}

在线聊天室
服务器:

public class Chat {
private static CopyOnWriteArrayList<channel> list=new CopyOnWriteArrayList<>();//使用并发容器,适合多线程
public static void main(String[]args) throws IOException
{
    System.out.println("服务器启动中...");

    ServerSocket server=new ServerSocket(9999);

    while(true)
    {
        Socket client =server.accept();
        System.out.println("一个客户端建立了连接");
        channel c=new channel(client);
        list.add(c);  //容器管理所有成员
        new Thread(c).start();

    }

}

static class channel implements Runnable{
    private DataInputStream dis;
    private DataOutputStream dos;
    private BufferedReader br;
    private Socket client;
    private boolean flag;
    private String name;

    public channel(Socket client)
    {
        this.client=client;
        try {
            dis=new DataInputStream(client.getInputStream());
            dos=new DataOutputStream(client.getOutputStream());
            flag=true;

            //获取名称
            this.name=receive();
            //欢迎到来
            this.send("欢迎来到聊天室");
            this.sendothers(this.name+"来到了聊天室",true);

        } catch (IOException e) {
            release();          }
    }
    //接收消息
    private String receive()
    {
        try {
            String msg=dis.readUTF();
            return msg;
        } catch (IOException e) {
            release();
        }
        return null;

    }
    //发送给消息
    private void send(String msg)
    {
        try {
            dos.writeUTF(msg);
            dos.flush();
        } catch (IOException e) {
            release();
        }

    }
    //群聊:获取自己的消息,发给其他人和私聊功能
    private void sendothers(String msg,boolean issys)
    {
        boolean issecrete =msg.startsWith("@");
        if(issecrete)
        {
            int index=msg.indexOf(":");
            String target=msg.substring(1,index);
            msg=msg.substring(index+1);

            for(channel it:list)
            {
                if(it.name.equals(target)) //查找目标
                {
                    it.send(this.name+"悄悄地对你说:"+msg); //私聊消息
                    break;
                }
            }
        }else
        {
            for(channel it:list)
            {
                if(it==this)
                {
                    continue;
                }
                if(!issys)
                {
                    it.send(this.name+":"+msg);
                }else
                {
                    it.send(msg);
                }
            }
        }
    }
    private void release()
    {
        this.flag=false;
        utils.close(dis,dos,client); //写一个工具类,使用Closeable...可变参数
        //退出时,从容器里面移掉自身
        list.remove(this);
        sendothers("离开了聊天室",false);
    }
    public void run()
    {
        while(flag)
        {
            String msg=receive();
            sendothers(msg,false);
        }
        release();

    }

}
}

原文地址:https://blog.51cto.com/14437184/2433878

时间: 2024-11-16 23:50:58

java 网络编程-TCP-多人群聊究极版的相关文章

JAVA网络编程-----tcp

java采用TCP传输时利用Socket和ServerSocket Socket和ServerSocket 建立客户端和服务端 建立连接后,通过Socket中的IO流进行数据的传输. 关闭Socket 同样,客户端与服务端是两个独立的应用程序. 演示tcp传输 1.   tcp分客户端和服务端 2.   客户端对应的对象是Socket,服务端对应的对象是ServerSocket. 客户端: 通过查阅socket对象,发现在该对象建立时,就可以连接指定主机, 因为tcp是面向连接的,所以在建立so

Java网络编程TCP程序,服务器和客户机交互流程以及基本操作步骤。

1.什么是网络编程 网络编程其实就是实现两个计算机的数据交换(交互). 可以通过直接或间接的通过网络协议与其他的计算机进行通讯.(HTTP协议,TCP/IP协议等) 2.Tcp网络编程的实现流程 主要分为服务器端(Server)和客户端(Client). 通过这个图我们其实就可以了解了实现服务器和客户机交互过程是怎么样的了. 实现这些原理最重要的是Socket类也叫做套接字.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 服务器端 1.首先创建ServerSocket对象并

JAVA网络编程TCP通信

Socket简介: Socket称为"套接字",描述IP地址和端口.在Internet上的主机一般运行多个服务软件,同时提供几种服务,每种服务都打开一个Socket,并绑定在一个端口上,不同的端口对应于不同的服务.Socket和ServerSocket类位于java.net包中.ServerSocket用于服务端,Socket是建立网络连接时使用的.连接成功时,应用程序两端都会产生一个Socket实例,通过操作这个实例完成所需会话. Socket常用方法: -int getLocalP

java网络编程TCP

图片来自网络 [服务端] import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; //服务端 public class MyServer { public static void main(String[] args) { ServerSocket serverSocket =

Java网络编程のTCP/IP

TCP/IP参考模型和TCP/IP协议 与OSI参考模型相似,TCP/IP参考模型汲取了网络分层的思想,而且对网络的层次做了简化,并在网络各层都提供了完善的协议,这些协议构成了TCP/IP协议集,简称TCP/IP协议. TCP/IP参考模型分为4个层次:应用层.传输层.网络互连层和主机-网络层.在每一层都有相应的协议.确切地说,TCP/IP协议应该称为TCP/IP协议集,它是TCP/IP参考模型的除了主机-网络层(由第三方提供)以外的其他三层的协议的集合,而IP协议和TCP协议则是协议集中最核心

JAVA网络编程TCP案例

服务端 import java.net.*; import java.io.*; public class TCPServerSocket { public static void main(String[] args) throws Exception{ String data = ""; //while (true) { try{ ServerSocket ss = new ServerSocket(8888); Socket s = ss.accept(); InputStrea

java 网络编程 TCP协议 java 服务器和客户端 java socket编程

一个 HelloWord 级别的 Java Socket 通信的例子.通讯过程:        先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求.然后运行 Client 端,客户端发出连接请求,服务端监听到这次请求后向客户端发回接受消息,连接建立,启动一个线程去处理这次请求,然后继续死循环监听其他请求.客户端输入字符串后按回车键,向服务器发送数据.服务器读取数据后回复客户端数据.这次请求处理完毕,启动的线程消亡.如果客户端接收到 "OK" 之外的返回数据,会再次

Java网络编程(TCP协议-服务端和客户端交互)

客户端: 1 package WebProgramingDemo; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.OutputStream; 6 import java.net.Socket; 7 import java.net.UnknownHostException; 8 9 public class SocketDemo { 10 11 /** 12 * @param args

Java网络编程(TCP客户端)

1 package WebProgramingDemo; 2 3 import java.io.IOException; 4 import java.io.OutputStream; 5 import java.net.Socket; 6 import java.net.UnknownHostException; 7 8 public class SocketDemo { 9 10 /** 11 * @param args 12 * @throws IOException 13 * @throw