——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
【基本原理】
1:对于基本聊天程序而言,需要传输的及时数据一般不大,但要求传输速度快。因此,一般情况下,聊天软件都采用UDP协议进行数据传输。
2:聊天程序代码可以分为三部分,UDP接收端,UDP发送端,主程序。对于发送端而言,注意在数据的打包过程中就已经把发送的目的地已经封装在包中,而不是定义的DatagramSocket对象里。而对于接受端而言,从哪里接受数据时由DatagramSocket对象初始化决定的(及创建DatagramSocket对象时传递的prot值),而与数据的包无关。
3:对于及时聊天程序,接收和发送时同时进行的。因此,需要采用java 的多线程技术。在实际运用中,多线程的实现方法有两种,一种是继承Thread类,另外一张是实现Runnable接口。在考虑到java语法中继承属于单继承,故采用第二种方法。
4:PS:案例中的IP地址127.0.0.1为本地回环地址,及发送和接受都是同一个IP。如果ping hostname不通的话,可能是网卡已经失效。
【UDP发送端】
package qq_demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//QQ聊天程序,采用UDP传输协议;实时,无需建立连接,快速但不可靠。
public class QQ_send implements Runnable {
//私有成员变量 DatagramSocket的一个对象
private DatagramSocket ds;
//构造函数,传递Socket服务个QQ发送端
public QQ_send(DatagramSocket ds){
this.ds=ds;
}
//实现的Runnable接口,实现的run方法
@Override
public void run() {
//键盘录入
BufferedReader bufr=new
BufferedReader(new InputStreamReader(System.in) );
String line=null;
try{
//逐行读取键盘录入并且打包发送
while((line=bufr.readLine())!=null){
byte[] DataBuff=line.getBytes();
DatagramPacket dp=new
DatagramPacket(DataBuff, DataBuff.length, InetAddress.getByName("127.0.0.1"), 10004) ;
ds.send(dp);
//定义键盘录入结束标志
if(line.equals("end")) break;
}
} catch (IOException e){
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//发送结束,关闭资源
ds.close();
}
}
【UDP接收端】
package qq_demo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class QQ_receive implements Runnable{
//私有成员变量
private DatagramSocket ds;
//构造函数,传递参数
public QQ_receive(DatagramSocket receive)
{
this.ds=receive;
// TODO 自动生成的构造函数存根
}
//实现run方法
@Override
public void run() {
while(true){
try{
//定义数据缓存区
byte[] ReceBuff=new byte[1024];
//数据解包
DatagramPacket dp=new DatagramPacket(ReceBuff,ReceBuff.length);
//接收指定端口的数据内容
ds.receive(dp);
//获取内容的IP地址 和内容
String ip =dp.getAddress().getHostAddress();
int port =dp.getPort();
String data=new String(dp.getData(),0,dp.getLength());
//控制台输出内容
System.out.println("IP:"+ip+" "+data.toUpperCase());
if(data.equals(null)){System.out.println("发送消息为空");}
if(data.equalsIgnoreCase("end")){System.out.println("聊天结束");}
//异常机制
} catch (IOException e){
e.printStackTrace();
}
//ds.close();
}
}
}
【主程序】
package qq_demo;
import java.net.DatagramSocket;
import java.net.SocketException;
public class QQ_MAIN{
public static void main(String[] args) throws SocketException {
//创建两个DatagramSocket对象,其中,接收端必须指定端口
DatagramSocket send=new DatagramSocket();
DatagramSocket receive=new DatagramSocket(10004);
//执行线程
new Thread(new QQ_send(send)).start();
new Thread(new QQ_receive(receive)).start();
}
}