基于UDP协议的控制台聊天

时间:2024-09-29 09:37:38

这几天学了java的网络编程弄出一个基于UDP协议的聊天工具

功能

添加并且备注好友(输入对方的ip)

删除好友

查看好友列表

用java写的控制台程序导出可执行程序后不能双击打开
还需要些一个脚本文件(前提是电脑需装有jre运行环境)
java -jar %1
pause
然后保存bat文件  将jar文件用这个bat文件打开就可以了
源码:
package udp;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class UDPspend
{
    static DatagramPacket packet = null;// 用于发送数据的包
    static DatagramSocket socket = null;// 用于发送数据
    static DatagramPacket packet1 = null;// 用于接收数据的包
    static DatagramSocket socket1 = null;// 用于接收数据
    static final int port = 8087;
    static byte[] info1 = new byte[2048];// 接收的数据放到此数组内
    static String duiFangIpString = null;// 与之对话的ip地址
    static List<String> list = new ArrayList<String>();// 用于保存好友的ip信息
    static List<String> listName = new ArrayList<String>();// 用于保存好友的姓名
    static int dangQian = 0;
    static int count = 0;
    public static void send(String ip, String info) throws Exception
    {
        byte message[] = info.getBytes();// 将要发送的内容放到字节数组中
        InetAddress addr = InetAddress.getByName(ip);//由于datagramPacket()构造器中智只能传入InetAddress类型的所以~
        packet = new DatagramPacket(message, message.length, addr, port);//将数据封包
        socket = new DatagramSocket();//创建一个对象用来发送包
        socket.send(packet);//发送包
        // System.out.println("已发送");
    }
    public static void receive() throws Exception
    {
        socket1 = new DatagramSocket(port);//监视这个port端口
        packet1 = new DatagramPacket(info1, info1.length);//将接收的内容存入info1字节数组中
        class jieShou extends TimerTask//创建一个定时的任务,每隔一段时间内就扫描一下这个端口有没有发来的信息
        {
            public void run()
            {
                try
                {
                    socket1.receive(packet1);//接收数据包
                    String message = null;
                    message = new String(info1, 0, packet1.getLength());//将字节转换为字符串
                    String name = packet1.getAddress().toString().replaceAll("/", "");//得到发送对象的地址 
                    // System.out.println(name);
                    int i = list.indexOf(name);//在好友列表内寻找有没有这个地址
                    if (i == -1)//没有找到
                    {
                        name = "陌生人";
                    } else
                    {
                        name = listName.get(i);//找到了  并得到此好友ip地址的备注
                    }
                    System.out.println(name + " :  " + message);
                    packet1.setLength(info1.length);//重设接收包的长度,即接收的内容只能是此字节数组的长度大于此长度的内容 会自动舍弃  ,最大为64K
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
        jieShou jieShou = new jieShou();
        Timer timer = new Timer();
        timer.schedule(jieShou, 100, 1000);//从程序运行后100毫秒启动任务  并每隔1000毫秒执行一次此任务
    }
    public static void listFriends()//显示好友信息
    {
        if (count == 0)
            System.out.println("你目前没有好友");
        for (int i = 0; i < count; i++)
        {
            System.out.println(i + 1 + "     " + listName.get(i) + "     " + list.get(i));
        }
    }
    public static void addFriend()//添加好友
    {
        Scanner sc = new Scanner(System.in);//不能读入空格
        BufferedReader sc1=new BufferedReader(new InputStreamReader(System.in));//可以读入空格
        System.out.println("请输入姓名");
        String nameString=null;
        try
        {
              nameString =sc1.readLine();//输入姓名
        } catch (Exception e)
        {
            System.out.println("输入姓名发生错误");
        }
        System.out.println("请输入ip");
        String ipString = sc.next();
        //用正则表达式来验证输入的ip地址是否合法
        if (!ipString
                .matches("(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)"))
            System.out.println("ip格式错误");
        else if (list.indexOf(ipString)<count&&list.indexOf(ipString)>=0)
        {
            System.out.println("此好友已经存在");
        } else
        {
            try
            {
                InetAddress address = InetAddress.getByName(ipString);
                list.add(address.toString().replaceAll("/", ""));
                listName.add(nameString);
                count++;//添加好友到列表
                addHaoYou(nameString, ipString,true);//将好友信息保存到文件中
            } catch (Exception e)
            {
                // TODO: handle exception
                System.out.println("添加好友失败");
            }
            System.out.println("添加好友成功");
        }
    }
    public static void delete()//删除好友
    {
        for(int i=dangQian;i<count-1;i++)
        {
            list.set(i, list.get(i+1));
            listName.set(i, listName.get(i+1));
        }
        count--;//删除一位好友
        addHaoYou("", "",false);//清空文件保存的好友信息
        for(int i=0;i<count;i++)//将所有的好友信息重新写入文件
            addHaoYou(listName.get(i),list.get(i),true);
        System.out.println("删除成功");
    }
    public static void huiHua()//会话
    {
        if (count == 0)
        {
            System.out.println("你目前没有好友,请添加好友");
            addFriend();
        } else
        {
            listFriends();
            System.out.println("请选择你的好友 编号");
            Scanner sc = new Scanner(System.in);
            int op = 0;
            String n = null;
            while (op == 0)
            {
                n = sc.next();
                if (n.matches("\\d*") && Integer.valueOf(n) > 0 && Integer.valueOf(n) <= count)//输入的数据不合法
                    op = 1;
                else
                {
                    System.out.println("没有这个编号,请重新输入");
                    op = 0;
                }
            }
            BufferedReader sc1=new BufferedReader(new InputStreamReader(System.in));
            dangQian = Integer.valueOf(n)-1;
            System.out.println("开始会话,输入00000退出会话");
            String info;
            try
            {
                while (true)
                {
                    info = sc1.readLine();
                    if (info.equals("00000"))
                        break;
                    else if (info.equals("@add@"))
                    {
                        addFriend();
                        break;
                    } else if (info.equals("@list@"))
                    {
                        listFriends();
                        // break;
                    } else if(info.equals("@delete@"))
                    {
                        delete();
                        break;
                    }
                    else 
                    {
                        duiFangIpString = list.get(Integer.valueOf(n) - 1).toString();
                        send(duiFangIpString, info);
                    }
                }
            } catch (Exception e)
            {
                System.out.println("会话错误");
            }
        }
    }
    public static void duQuHaoYou()//从文件中读取好友的信息
    {
        try
        {
            File file = new File("haoyou");
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            String temp = null;
            String[] name = new String[2];
            while ((temp = in.readLine()) != null)
            {
                // System.out.println(11);
                name = temp.split("#");//以#为分隔符  前面是姓名 后面是ip
                listName.add(name[0]);
                list.add(name[1]);
                count++;
            }
        } catch (Exception e)
        {
            System.out.println("读取好友信息失败");
        }
    }
    public static void addHaoYou(String name, String ip,boolean b)//当b为真时 以追加的方式写入文件   当b为假时  清空原来的文件内容然后重新写入
    {
        try
        {
            FileWriter out = new FileWriter("haoyou",b);
            if(b==false)
                out.write("");
            else 
            out.write(name + "#" + ip+"\r\n");//在windows操作系统下  回车+换行才是一个真正的换行
            out.flush();//这里一定要刷新  否则不会写到文件中  数据还保存在缓冲区中  除非缓冲区满了
        } catch (Exception e)
        {
            // TODO: handle exception
        }
    }
    public static void main(String[] args) throws Exception
    {
        InetAddress address=InetAddress.getLocalHost();
        System.out.println("本机地址: "+address.getHostAddress());
        System.out.println("使用须知    在会话界面输入 \n@list@  显示好友信息\n@add@  添加好友\n@delete@  删除好友\n00000  退出会话 ");
        duQuHaoYou();
        receive();
        while (true)
        {
            huiHua();
        }
    }
}