java中UDP简单聊天程序实例代码
学过计算机网络通信的都知道,计算机之间传送数据由两种,即tcp通信和udp通信。tcp是可靠的面向连接的通信协议,二udp是不可靠的面向无连接的通信协议。
java中有基于tcp的网络套接字通信,也有基于udp的用户数据报通信,udp的信息传输速度快,但不可靠!
基于udp通信的基本模式:
(1)将数据打包,称为数据包(好比将信件装入信封一样),然后将数据包发往目的地。
(2)接受别人发来的数据包(好比接收信封一样),然后查看数据包中的内容。
客户机
package com.client.view;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
import java.awt.event.windowadapter;
import java.awt.event.windowevent;
import java.io.objectoutputstream;
import javax.swing.imageicon;
import javax.swing.jbutton;
import javax.swing.jframe;
import javax.swing.joptionpane;
import javax.swing.jpanel;
import javax.swing.jtextarea;
import javax.swing.jtextfield;
import com.tools.clienttoserverthread;
/**
* @author lenovo
*
*/
public class jchatfrm extends jframe implements actionlistener{
jtextarea jta;
jtextfield jtf;
jbutton jb;
jpanel jp;
string ownerid;
string friendid;
clienttoserverthread ctst;
public static void main(string[] args) {
// todo auto-generated method stub
new jchatfrm();
}
public jchatfrm()
{
settitle("客户端");
jta=new jtextarea();
jtf=new jtextfield(15);
jb=new jbutton("发送");
jb.addactionlistener(this);
jp=new jpanel();
jp.add(jtf);
jp.add(jb);
this.add(jta,"center");
this.add(jp,"south");
// this.settitle(ownerid+" 正在和 "+friend+" 聊天");
this.seticonimage((new imageicon("image/qq.gif").getimage()));
// this.setsize(300, 200);
this.setbounds(300, 200, 300, 200);
this.setvisible(true);
setdefaultcloseoperation(jframe.dispose_on_close);
ctst = new clienttoserverthread(jta);
ctst.start();
/**窗体关闭按钮事件*/
this.addwindowlistener(new windowadapter()
{
public void windowclosing(windowevent e)
{
if(joptionpane.showconfirmdialog(null, "<html><font size=3>确定退出吗?</html>","系统提示",joptionpane.ok_cancel_option,joptionpane.information_message)==0)
{
system.exit(0);
ctst.closesocket();
}
else
{
return;
}
}
}
);
}
//写一个方法,让它显示消息
public void showmessage(string message)
{
string info= message;
this.jta.append(info);
}
public void actionperformed(actionevent arg0) {
// todo auto-generated method stub
if(arg0.getsource()==jb)
{
byte buffer[] = jtf.gettext().trim().getbytes();
ctst.senddata(buffer);
}
}
}
package com.tools;
import java.io.ioexception;
import java.io.inputstream;
import java.io.objectinputstream;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;
import java.net.socket;
import java.util.properties;
import javax.swing.jtextarea;
import com.common.user;
/**
* @author lenovo
*
*/
public class clienttoserverthread extends thread{
private string serverip = "127.0.0.1";
private int serverport = 8888;
private int receiveport = 6666;
//声明发送信息的数据报套结字
private datagramsocket sendsocket = null;
//声明发送信息的数据包
private datagrampacket sendpacket = null;
//声明接受信息的数据报套结字
private datagramsocket receivesocket = null;
//声明接受信息的数据报
private datagrampacket receivepacket = null;
//收发数据的端口
private int myport = 0;
//接收数据主机的ip地址
private string friendip = null;
private int friendport = 0;
//缓冲数组的大小
public static final int buffer_size = 5120;
private byte inbuf[] = null; //接收数据的缓冲数组
private byte outbuf[] = null; //发送数据的缓冲数组
jtextarea jta;
// 构造函数
public clienttoserverthread(jtextarea jta) {
this.jta = jta;
getpropertiesinfo();
}
public void run() {
string receiveinfo = "";
try{
inbuf = new byte[buffer_size];
receivepacket = new datagrampacket(inbuf,inbuf.length);
receivesocket = new datagramsocket(receiveport);
}catch (exception e) {
e.printstacktrace();
// todo: handle exception
}
while (true) {
if(receivesocket == null){
break;
} else {
try {
receivesocket.receive(receivepacket);
string message = new string(receivepacket.getdata(),0,receivepacket.getlength());
jta.append("收到数据"+message+"\n");
} catch (exception e) {
e.printstacktrace();
// todo: handle exception
}
}
}
}
/**
* 该方法用来获得服务器属性文件中的ip、port
*/
private void getpropertiesinfo(){
properties prop = new properties();
inputstream instream = thread.currentthread().getcontextclassloader()
.getresourceasstream("serverinfo.properties");
try{
//获得相应的键值对
prop.load(instream);
}catch(ioexception e){
e.printstacktrace();
}
//根据相应的键获得对应的值
serverip = prop.getproperty("serverip");
serverport = integer.parseint(prop.getproperty("serverudp.port"));
receiveport = integer.parseint(prop.getproperty("receiveudp.port"));
}
public void senddata(byte buffer[]){
try{
inetaddress address = inetaddress.getbyname(serverip);
// outbuf = new byte[buffer_size];
sendpacket = new datagrampacket(buffer,buffer.length,address,serverport);
sendsocket = new datagramsocket();
sendsocket.send(sendpacket);
}catch (exception e) {
e.printstacktrace();
// todo: handle exception
}
}
public void closesocket(){
receivesocket.close();
}
}
服务器:
package com.server.view;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
import java.awt.event.windowadapter;
import java.awt.event.windowevent;
import java.io.objectoutputstream;
import javax.swing.imageicon;
import javax.swing.jbutton;
import javax.swing.jframe;
import javax.swing.joptionpane;
import javax.swing.jpanel;
import javax.swing.jtextarea;
import javax.swing.jtextfield;
import com.tools.clienttoserverthread;
/**
* @author lenovo
*
*/
public class jchatfrm extends jframe implements actionlistener{
jtextarea jta;
jtextfield jtf;
jbutton jb;
jpanel jp;
string ownerid;
string friendid;
clienttoserverthread ctst;
public static void main(string[] args) {
// todo auto-generated method stub
new jchatfrm();
}
public jchatfrm()
{
settitle("服务器");
jta=new jtextarea();
jtf=new jtextfield(15);
jb=new jbutton("发送");
jb.addactionlistener(this);
jp=new jpanel();
jp.add(jtf);
jp.add(jb);
this.add(jta,"center");
this.add(jp,"south");
// this.settitle(ownerid+" 正在和 "+friend+" 聊天");
this.seticonimage((new imageicon("image/qq.gif").getimage()));
// this.setsize(300, 200);
this.setbounds(300, 200, 300, 200);
this.setvisible(true);
setdefaultcloseoperation(jframe.dispose_on_close);
ctst = new clienttoserverthread(jta);
ctst.start();
/**窗体关闭按钮事件*/
this.addwindowlistener(new windowadapter()
{
public void windowclosing(windowevent e)
{
if(joptionpane.showconfirmdialog(null, "<html><font size=3>确定退出吗?</html>","系统提示",joptionpane.ok_cancel_option,joptionpane.information_message)==0)
{
system.exit(0);
ctst.closesocket();
}
else
{
return;
}
}
}
);
}
//写一个方法,让它显示消息
public void showmessage(string message)
{
string info= message;
this.jta.append(info);
}
public void actionperformed(actionevent arg0) {
// todo auto-generated method stub
if(arg0.getsource()==jb)
{
byte buffer[] = jtf.gettext().trim().getbytes();
ctst.senddata(buffer);
}
}
}
package com.tools;
import java.io.ioexception;
import java.io.inputstream;
import java.io.objectinputstream;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;
import java.net.socket;
import java.util.properties;
import javax.swing.jtextarea;
import com.common.user;
/**
* @author lenovo
*
*/
public class clienttoserverthread extends thread{
private string sendip = "127.0.0.1";
private int sendport = 6666;
private int receiveport = 8888;
//声明发送信息的数据报套结字
private datagramsocket sendsocket = null;
//声明发送信息的数据包
private datagrampacket sendpacket = null;
//声明接受信息的数据报套结字
private datagramsocket receivesocket = null;
//声明接受信息的数据报
private datagrampacket receivepacket = null;
//收发数据的端口
private int myport = 0;
//接收数据主机的ip地址
private string friendip = null;
private int friendport = 0;
//缓冲数组的大小
public static final int buffer_size = 5120;
private byte inbuf[] = null; //接收数据的缓冲数组
private byte outbuf[] = null; //发送数据的缓冲数组
jtextarea jta;
// 构造函数
public clienttoserverthread(jtextarea jta) {
this.jta = jta;
getpropertiesinfo();
}
public void run() {
string receiveinfo = "";
try{
inbuf = new byte[buffer_size];
receivepacket = new datagrampacket(inbuf,inbuf.length);
receivesocket = new datagramsocket(receiveport);
}catch (exception e) {
e.printstacktrace();
// todo: handle exception
}
while (true) {
if(receivesocket == null){
break;
} else {
try {
receivesocket.receive(receivepacket);
string message = new string(receivepacket.getdata(),0,receivepacket.getlength());
jta.append("收到数据"+message+"\n");
} catch (exception e) {
e.printstacktrace();
// todo: handle exception
}
}
}
}
/**
* 该方法用来获得服务器属性文件中的ip、port
*/
private void getpropertiesinfo(){
properties prop = new properties();
inputstream instream = thread.currentthread().getcontextclassloader()
.getresourceasstream("serverinfo.properties");
try{
//获得相应的键值对
prop.load(instream);
}catch(ioexception e){
e.printstacktrace();
}
//根据相应的键获得对应的值
receiveport = integer.parseint(prop.getproperty("serverudp.port"));
}
public void senddata(byte buffer[]){
try{
inetaddress address = inetaddress.getbyname(sendip);
// outbuf = new byte[buffer_size];
sendpacket = new datagrampacket(buffer,buffer.length,address,sendport);
sendsocket = new datagramsocket();
sendsocket.send(sendpacket);
}catch (exception e) {
e.printstacktrace();
// todo: handle exception
}
}
public void closesocket(){
receivesocket.close();
}
}
运行截图: