基于UDP协议的控制台聊天
这几天学了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());
duQuHaoYou();
receive();
while (true)
{
huiHua();
}
}
}
梦里不知身是客,一晌贪欢。