• Socket通信 简单实现私聊、群聊(dos命令下)


    很久以前的一个Demo,这里服务器只做转发功能,根据ID地址和端口号来标识身份,群聊和私聊只是简单实现,

    服务器代码如下:

    import java.util.*;
    import java.io.*;
    import java.net.*;
    
    public class Server extends Thread 
    {
        private static Vector<Socket> vecClient = new Vector<Socket>(); 
        private PrintWriter out;
        private BufferedReader in;
        private Socket clientsocket;
    
        public static void main(String[] args) throws IOException {
            ServerSocket server = new ServerSocket(2014); // 创建
            System.out.println("启动服务器! ");
            Socket sock;
    
            while (true) {
                sock = server.accept(); // 等待客户请求
                Server ser = new Server(sock); 
                ser.start(); // 启动
            }
        }
    
        public Server(Socket socket) {
            this.clientsocket = socket;
            vecClient.addElement(socket); // 增加客户线程到数组
            try {
                // 获取服务端传来的字节流好,存到缓冲区
                in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));
                // printwriter,文本输出流打印对象的格式化表示形式,只有调用println等,自动刷新即true,强行把缓冲区的数据输出。
                out = new PrintWriter(new OutputStreamWriter(
                        socket.getOutputStream()), true);
                // input、OutputStreamWriter 是字符流通向字节流的桥梁
            } catch (IOException e) {
            }
        }
    
        public void run()             
        {        
            try
            { 
                Newclient();          // 向新客户发出欢迎信息,通知所有在线客户有新客户连接了
                while(true)          // 处理与客户的交流
                {
                    String msg=in.readLine();    //数据读取      
                    
                    if(msg.equals("bye")|| msg.equals("拜拜"))//当输入拜拜或bye时候退出
                    {
                        Xiaxian();             
                        in.close();          // 关闭输入流
                        clientsocket.close(); // 关闭socket
                        break;
                    }
                    else if(msg.indexOf("@")==0&&msg.indexOf(" ")>0){
                        int end=msg.indexOf(" ");
                        String findAddr=msg.substring(1,end);
                        if(vecClient.isEmpty() == false) //判断为空
                            {
                            for(int i=0;i<vecClient.size();i++)
                            {
                                Socket socket = vecClient.get(i);
                                String addr = socket.getInetAddress().toString().replace("/", "") + ":"
                                        + socket.getPort();
                                if(findAddr.equals(addr)){
                                    String addr2 = clientsocket.getInetAddress().toString().replace("/", "") + ":"
                                            + clientsocket.getPort();
                                    //elementAt返回指定索引处的组件,而get返回列表中指定位置处的元素
                                    PrintWriter pw = new PrintWriter(new OutputStreamWriter(vecClient.get(i).getOutputStream()),true); 
                                    pw.println("大神"+addr2+" 对你 说: "+msg.substring(end));
                                }
                            }
                            }
                    }
                    // 否则将接收到的信息向所有在线客户发出去
                    else
                    {
                        if(vecClient.isEmpty() == false) 
                            for(int i=0;i<vecClient.size();i++)
                            {
                                //elementAt返回指定索引处的组件,而get返回列表中指定位置处的元素
                                PrintWriter pw = new PrintWriter(new OutputStreamWriter(vecClient.get(i).getOutputStream()),true); 
                                pw.println("大神"+clientsocket.getInetAddress().toString()+":"+clientsocket.getPort()+" 说: "+msg);
                            }
                    }
                }
            }
            catch(IOException e)
            { }
        }
    
        public void Newclient() throws IOException // 新来的,用此函数
        {
            String addr = clientsocket.getInetAddress().toString() + ":"
                    + clientsocket.getPort();
            out.println("欢迎:" + addr+"加入! ");
            try {
                if (vecClient.isEmpty() == false)
                    for (int i = 0; i < vecClient.size(); i++)
                    {
                        Socket socket = vecClient.get(i);
                        PrintWriter pw = new PrintWriter(new OutputStreamWriter(
                                socket.getOutputStream()), true);
                        String addr2 = socket.getInetAddress().toString() + ":"
                                + socket.getPort();
                        if (addr.equals(addr2)) {
                            pw.println("欢迎加入聊天,私聊请用@ip:port 内容");
                        } else {
                            pw.println("新成员:"
                                    + clientsocket.getInetAddress().toString()
                                    + ":" + clientsocket.getPort() + "  嗨起来吧!");
                        }
                    }
            } catch (IOException e) {
            }
        }
    
        public void Xiaxian() throws IOException // 下线方法
        {
            out.println("再见,连接关闭!");
            if (vecClient.isEmpty() == false)
                for (int i = 0; i < vecClient.size(); i++) {
                    PrintWriter pw = new PrintWriter(new OutputStreamWriter(vecClient
                            .get(i).getOutputStream()), true);
                    pw.println("--" + clientsocket.getInetAddress().toString()
                            + ":" + clientsocket.getPort() + " 已经下线");
                }
            vecClient.remove(clientsocket); 
        }
    }
    View Code

    客服端,可在本地命令运行多个测试,私聊格式:@ip:port(这里必须有空格)内容,原理如下:

    import java.net.*;
    import java.io.*;
    import java.util.*;
    
    class Client
    {   
        public static void main(String[] args)
        {
            try
              {    
                    Socket socket=new Socket("localhost",2014);                                
                    ClientSend send=new ClientSend(socket);            // 创建发送线程
                    ClientReceive receive=new ClientReceive(socket); // 创建接收线程
                    send.start();                                       // 启动发送线程
                    receive.start();                                  // 启动接收线程
              }
            catch(Exception e) 
              {
                System.out.println("服务器没有开启呢!");
                e.printStackTrace();
              }
                       
        }
    }
    
    class ClientSend extends Thread
    {
        private Socket socket;
        private PrintWriter out;
        
        public ClientSend(Socket socket)
        {
            this.socket=socket;
            try
            {
                out=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
            //返回一个服务器与客户端的输出流,true强行把缓冲区的数据输出
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
        
        public void run()  // 发送信息到服务器
        {
            String msg;
            Scanner input=new Scanner(System.in);//输入
            msg = input.nextLine();                //nextLine方法返回的是回车之前的所有字符
            while(true)
            {
                //用equalsIgnoreCase可忽略大小写
                if(msg.equals("bye") || msg.equals("拜拜"))
                {
                    out.println(msg);
                    break;
                }                        
                out.println(msg);
                msg = input.nextLine();            
            }
        }
    }
    
    class ClientReceive extends Thread            //接收
    {
        private Socket socket;
        private BufferedReader in;
        
        public ClientReceive(Socket socket)
        {
            this.socket= socket;
            try
            {
                in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
        
        public void run() // 接收服务器发来的信息
        {        
            try
            {
                String msg=in.readLine();
                while(msg.equals("bye") == false)
                {
                    System.out.println(msg);
                    msg=in.readLine();
                }
                in.close();
                socket.close();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }        
        }
    }
    View Code
    业精于勤荒于嬉。
  • 相关阅读:
    halcon机器视觉工程开发思路
    创建子窗口新线程-线程间操作无效:从不是创建控件的线程访问它
    c#多个按钮执行同一类事件-按钮按下和弹起
    winform子窗口与父窗口的交互-使用委托与事件
    winform子窗口调用父窗口的控件及方法-一般调用
    Lambda表达式的用法
    c#WinForm中TeeChart控件的注册和使用
    c#实现串口通信
    [Revit]开始:编写一个简单外部命令
    [Revit]Autodesk Revit 二次开发整理(资料、准备工作和环境搭建)
  • 原文地址:https://www.cnblogs.com/mottled/p/5989126.html
Copyright © 2020-2023  润新知