此次的上手项目依然是基于Java编写实现的,在网络编程这块当中,可以利用UDP来实现类似于多人互相发消息的基本功能。
步骤一: 编写发送方
public class TalkSend{
public static void main(String[] args)throws Exception{//抛异常
DatagramSocket socket=new DatagramSocket(8888);
BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));//通过System.in输入控制台的数据
while(true){//循环发送
String data=buf.readLine();//读取一行数据
byte bytes=data.getBytes();//将数据转变为字节数组
DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress("localhost",6666));
socket.send(packet);//发送包
if(data.equals("byebye")){//断开连接的条件
break;
}
}
socket.close();
}
}
步骤二:编写接收方
public class TalkReceive{
public static void main(String[] args)throws Exception{
DatagramSocket socket =new DatagramSocket(6666);
while(true){//循环接收
byte[] container=new byte[1024];
DatagramPacket packet=new DatagramPacket(container,0,container.length)
socket.receive(packet);//接受包裹
byte[] data=packet.getData();
String receive=new String(data,0,data.length);
System.out.println(receive);//输出内容
if(receive.equals("bye")){
break;
}
}
socket.close();
}
}
步骤三:实现多线程在线聊天
在编写完发送方和接收方的类后,要实现类似于互相发短信的功能,必定要实现Runnable接口来实现多线程,并且可以对于发送方和接收方的两个类进行封装,在封装成一个工具类,要做到以下要求:
- 提前定义好全局变量,赋其为初始值;
- 定义构造方法,并将一些加载类同时需要调用的方法提取到构造方法当中,这样就实现了只要一加载类,就调用这些方法。
- 将经常使用的方法定义stactic方法,当多次调用这些方法时,就可以提高程序的执行效率。
发送方
public class TalkSend implements Runnable {
DatagramSocket socket=null;
BufferedReader buf=null;
private int fromPort;
private String toIP;//目的地IP
private int toPort;//目的地端口号
public TalkSend(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
socket=new DatagramSocket(fromPort);
//通过System.in读取控制台的数据
buf=new BufferedReader(new InputStreamReader(System.in));
}
catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
String data=buf.readLine();
byte[] bytes=data.getBytes();//使读取到的内容变为字节数组
DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress(this.toIP,this.toPort));
socket.send(packet);//发送包裹
if (data.equals("bye")){
break;
}
}
catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
接收方
public class TalkReceive implements Runnable {
DatagramSocket socket=null;
private int Port;
private String msgFrom;//发送者的来源
public TalkReceive(int fromPort,String msgFrom) {
this.Port = fromPort;
this.msgFrom=msgFrom;
try {
socket=new DatagramSocket(fromPort);
}
catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
byte[] container=new byte[1024];
DatagramPacket packet=new DatagramPacket(container,0,container.length);
socket.receive(packet);//接受包裹
//断开连接
byte[] bytes=packet.getData();//变为字节数组
String data=new String(bytes,0,bytes.length);
System.out.println(this.msgFrom+":"+data);
if (data.equals("bye")){//当匹配到bye时,断开连接
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
步骤四:编写测试类并调试运行
在编写测试类时,需要编写两个测试类,一方作为发送消息方,另一方作为接收方,但是,传递消息是双向的,也就是说,作为发送方也可以接收消息,作为接收方也可以发送消息。以学生和老师为例:
测试类
public class Teacher {
public static void main(String[] args) {
new Thread(new TalkSend(5555,"localhost",8888)).start();
new Thread(new TalkReceive(9999,"学生")).start();
}
}
public class Student {
public static void main(String[] args) {
new Thread(new TalkSend(7777,"localhost",9999)).start();
new Thread(new TalkReceive(8888,"老师")).start();
}
}
调试并运行
在idea中,由于两个窗口在控制台无法并排显示,所以无法直观的向大家展示,只可以切换类单显示。
学生窗口:
老师窗口:
可以在这个基础上再完善更多的功能模块,或者完善界面也是可以的。