这几天学了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. js微博发布框

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 京东电话面试——PHP开发

    1.学过<数据结构>吗?你学过的计算机相关课程有哪些? 2.web操作中,当你输入一个url到看到页面,描述一下这中间发生了什么? 3.TCP/IP的请求方式都有哪些? 4.POST和GE ...

  3. php 接口 implements 使用

    主要对类名,类所拥有的方法,以及所传参数起约束和规范做用,感觉跟php abstract 抽象类又有点像. 一,接口的定义和调用 <?php interface face1 { const pa ...

  4. 用开源软件构建App的高效服务端

    1.APP后端的重要性 2.架构目标与选型 3.Apache/Nginx? 4.为何选择Php 5.4? 5.Phalcon还是其它? 6.MySql 5.6 / MariaDB ? 7.Cobar: ...

  5. gcc -D选项

    一.概念 gcc的-D选项可以定义宏,这是什么意思呢? C语言源程序中有#define定义的宏,可以起到替换.条件编译的功能:定义宏的方式是放在头文件或者C文件中.gcc提供了另外一种宏定义的方法,当 ...

  6. 使用EF6.0出现:CS0029 无法将类型“System.Data.Entity.Core.Objects.ObjectContext”隐式转换为“System.Data.Objects.ObjectContext”错误

    这是因为EF6.0重构了一些命名空间后,和VS原有的实体数据模型模板不一致了(ObjectContext context = ((IObjectContextAdapter)dataContext). ...

  7. qt 5 基础知识 2(控件篇)

    QVBoxLayout *lay = new QVBoxLayout(this); // 创建一个竖直的盒子 lebel 篇 lay->addWidget(label = new QLabel( ...

  8. MYSQL数据库备份与恢复【转】

    mysqldump -h主机名  -P端口 -u用户名 -p密码 (–database) 数据库名 > 文件名.sql  在window上需要通过CMD进入mysql安装目录下的bin目录下执行 ...

  9. Dom学习笔记-(一)

    一.概述 DOM(文档对象模型)是针对HTML和XML文档的一个API,其脱胎于DHTML. DOM可以将任意HTML和XML文档描绘成一个由多层节点构成的结构. 每一个文档包含一个根节点-文档节点, ...

  10. 如何使用Github仓库创建网站

    官方文档:https://help.github.com/categories/github-pages-basics/ 1.创建一个仓库 2.额外建立一个gh-pages分支 3.添加CNAME文件 ...