这几天学了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();
        }
    }
}

基于UDP协议的控制台聊天的更多相关文章

  1. 基于UDP协议的控制台聊天程序(c++版)

    本博客由Rcchio原创,转载请告知作者 ------------------------------------------------------------------------------- ...

  2. 计算机网络课设之基于UDP协议的简易聊天机器人

    前言:2017年6月份计算机网络的课设任务,在同学的帮助和自学下基本搞懂了,基于UDP协议的基本聊天的实现方法.实现起来很简单,原理也很简单,主要是由于老师必须要求使用C语言来写,所以特别麻烦,而且C ...

  3. 网络编程应用:基于UDP协议【实现聊天程序】--练习

    要求: 使用UDP协议实现一个聊天程序 代码: 发送端: package UDP聊天程序; import java.io.IOException; import java.net.DatagramPa ...

  4. TCPIP协议编程:基于UDP协议的局域网聊天工具的研发

    任务目标 聊天器采用客户端/服务器(C/S)模式: 客户端利用UDP与服务器相连,客户端与客户端之间通过UDP相互通信: 服务器端具有服务器端口设置维护客户端个人信息,记录客户端状态,分配账号等: 客 ...

  5. python 全栈开发,Day34(基于UDP协议的socket)

    昨日内容回顾 网络的基础概念arp协议 :通过ip地址找到mac地址五层模型 : 应用层 传输层 网络层 数据链路层 物理层tcp协议 : 可靠的 面向连接 全双工 三次握手 四次挥手udp协议 : ...

  6. 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现

    一.客户端/服务器架构(C/S架构)                                                即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...

  7. 网络编程之基于UDP协议的套接字编程、基于socketserver实现并发的socket

    目录 基于UDP协议的套接字编程 UDP套接字简单示例 服务端 客户端 基于socketserver实现并发的socket 基于TCP协议 server类 request类 继承关系 服务端 客户端1 ...

  8. day31——recv工作原理、高大上版解决粘包方式、基于UDP协议的socket通信

    day31 recv工作原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据, For the opt ...

  9. 基于UDP协议的套接字编程

    基于udp协议的套接字编程 UDP是无链接的,先启动那一端都不会报错 UDP协议是数据报协议,发空的时候也会自带报头,因此客户端输入空,服务端也能收到 一般不用与传输大数据 虽然没有粘包问题,但是不能 ...

随机推荐

  1. Oracle的硬解析和软解析

    提到软解析(soft prase)和硬解析(hard prase),就不能不说一下Oracle对sql的处理过程.当你发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进 ...

  2. .net ajax式上传文件

    今天在这里介绍一下ajax上传文件.其实也不算是真的使用xmlhttprequest上传,只是使用了iframe实现了无刷新上传而已,最多也只算 是仿ajax上传文件.然而网上关于使用xmlhttpr ...

  3. demo——06弹性和制作骰子

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. [GUIDE] How to install Scipy in Maya Windows 64 bit - Google 网上论坛 - Google Chrome

    I've seen a lot of queries about getting scipy working in Maya (Windows 64 bit) with a few not 100% ...

  5. [原博客] POJ 1067 取石子游戏

    题目链接有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者 ...

  6. Ubuntu修改语言环境为英文

    转自把语言环境变量改为英文 将Ubuntu系统语言环境改为英文的en_US.UTF-8 查看当前系统语言环境 locale 编辑配置文件,将zh_US.UTF-8改为en_US.UTF-8,zh改为e ...

  7. Class类文件结构、类加载机制以及字节码执行

    一.Class类文件结构 Class类文件严格按照顺序紧凑的排列,由无符号数和表构成,表是由多个无符号数或其他数据项构成的符合数据结构. Class类文件格式按如下顺序排列:   类型 名称 数量 u ...

  8. Sql中的datetime类型的空值和c#中的DateTime的空值的转换方法

    [一篮饭特稀原创,转载请注明出自http://www.cnblogs.com/wanghafan/p/3412796.html] 在NET 2.0以上版本提供了一种新的方法 就是加问号,DateTim ...

  9. [转贴]JAVA 百度地图SDK地图学习——实现定位功能

    之前已经完成了百度地图SDK和百度定位SDK的配置. http://my.oschina.net/u/1051634/blog/180880 实现百度定位的功能,最好仔细看看官方的文档,看了好几次才有 ...

  10. [转贴] C++内存管理检测工具 Valgrind

    用C/C++开发其中最令人头疼的一个问题就是内存管理,有时候为了查找一个内存泄漏或者一个内存访问越界,需要要花上好几天时间,如果有一款工具能够帮助我们做这件事情就好了,valgrind正好就是这样的一 ...