这几天学了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. ellang 中进程异步通信中的信箱与保序

    erlang 进程通讯中 执行到 receive 语句时 如果信箱没有消息可以匹配时会暂停等待消息. go() -> register(echo, spawn(test_pid,loop,[]) ...

  2. javascript 对象的创建,引用,释放,删除方法

    1.用函数构造 A.声明时同时设置属性和方法 function func(){  this.name = "myname";  this.say = function(){aler ...

  3. 为 DataGridView 控件添加行号

    虽然好像不经常用到,不过还是记下来防止以后用到 /// <summary> /// 为 DataGridView 控件添加行号 /// </summary> /// <p ...

  4. DISC免费性格测试题

    现在给大家推荐一款世界500强和猎头公司招聘人才时用的DISC性格测评,用在找对象方面也比较合适.大家不妨看下自己的性格,就知道该找什么样的意中人啦--- 在每一个大标题中的四个选择题中只选择一个最符 ...

  5. gulp最佳实践(包含js,css,html预编译,合并,压缩,浏览器自动刷新)

    gulp是基于流的自动化构建工具官方网址:http://www.gulpjs.com.cn/ 一.安装需要的模块 1.新建package.json,输入下面的内容 { "name" ...

  6. Activity的窗口对象(Window)的创建过程分析

    与Activity组件所关联的窗口对象的实际类型为PhoneWindow,后者是从Window类继承下来的. Activity.Window和PhoneWindow三个类的关系如下 PhoneWind ...

  7. Mvc学习笔记(2)

    Razor模板的具体语法使用 因为Razor模板的可以自动识别<>,大大减少了代码量,本节我们一起来探究Razor模板的语法的简单应用: MVC知识点: 1.ASP.NET Mvc框架 是 ...

  8. iOS性能调优

    写在前面 本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelofabri.com/ ...

  9. CocoaPods安装和使用及问题:Setting up CocoaPods master repo-b

    目录 CocoaPods是什么? 如何下载和安装CocoaPods? 如何使用CocoaPods? 场景1:利用CocoaPods,在项目中导入AFNetworking类库 场景2:如何正确编译运行一 ...

  10. Quartz1.8.5例子(十)

    /* * Copyright 2005 - 2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the ...