UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。由于数据量小且不保证可靠性,适合即时通讯功能;
源代码已上传我的资源页http://download.csdn.net/detail/u012373815/8953825
实现代码如下:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JLabel;
/*
* author yang 2015 7 7udp
*/
publicclassGuiChat extends JFrame{
privatestatic intDEFULT_PORT ;
private JLabelstateLB;
private JTextAreacenterTextArea , inputTextArea;
private JPanelsouthPanel,bottompanel;
private JTextFieldipTextField,remotePortTF;
private JButtonsendBT,clearBT;
private DatagramSocketdatagramSocket;
publicvoid setUpUI(){
setTitle("客户端");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setResizable(false); //窗口大小不可调整
setLocationRelativeTo(null);//窗口剧中
stateLB =new JLabel("当前监听还未启动");
stateLB.setHorizontalAlignment(JLabel.RIGHT);
//窗口的center部分
centerTextArea=new JTextArea();
centerTextArea.setEditable(false);
centerTextArea.setBackground(new Color(211, 211, 211));
//窗口的SHOTU部分
southPanel =new JPanel(new BorderLayout());
inputTextArea=new JTextArea(5,20);
bottompanel=new JPanel(new FlowLayout(FlowLayout.CENTER,5,5));
ipTextField=new JTextField("127.0.0.1",8);
try {//输入本机端口号
DEFULT_PORT=Integer.parseInt(JOptionPane.showInputDialog(this,"请输入客户端的端口号","端口号",JOptionPane.QUESTION_MESSAGE));
if(DEFULT_PORT<1||DEFULT_PORT>65535)
{
thrownew RuntimeException("端口号超出范围");
}
}catch(Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(GuiChat.this,"你输入的端口号不正确,请输入1~65535之间的数");
}
remotePortTF=new JTextField(String.valueOf(DEFULT_PORT),3);
remotePortTF.setEditable(false);
sendBT=new JButton("发送");
clearBT=new JButton("清屏");
bottompanel.add(ipTextField);
bottompanel.add(remotePortTF);
bottompanel.add(sendBT);
bottompanel.add(clearBT);
southPanel.add(new JScrollPane(inputTextArea),BorderLayout.CENTER);
southPanel.add(bottompanel,BorderLayout.SOUTH);
add(stateLB,BorderLayout.NORTH);
add(new JScrollPane(centerTextArea),BorderLayout.CENTER);
add(southPanel,BorderLayout.SOUTH);
setVisible(true);
}
publicvoid setListener(){
sendBT.addActionListener(new ActionListener() {
@Override
publicvoidactionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
final String ipaddress=ipTextField.getText();
final String remoteport=remotePortTF.getText();
if(ipaddress==null||remoteport.trim().equals(""))
{
JOptionPane.showMessageDialog(GuiChat.this,"请输入IP地址和端口号");
return ;
}
Stringsendcontent=inputTextArea.getText();
byte []buf=sendcontent.getBytes();
try {
centerTextArea.append("我对"+ipaddress+":"+remoteport+"说:\n"+inputTextArea.getText()+"\n\n");
centerTextArea.setCaretPosition(centerTextArea.getText().length());
datagramSocket.send(new DatagramPacket(buf,buf.length,
InetAddress.getByName(ipaddress),Integer.parseInt(remoteport)));
inputTextArea.setText("");
}catch(Exception e2) {
// TODO: handle exception
JOptionPane.showMessageDialog(GuiChat.this,"出错了发送不成功");
e2.printStackTrace();
}
clearBT.addActionListener(new ActionListener() {
@Override
publicvoidactionPerformed(ActionEvent e) {
centerTextArea.setText("");//清空聊天记录
}
});
}
});
}
//填写程序监听的端口号
publicvoid initSocket(){
int port=DEFULT_PORT;
while(true)
{
try {
if(datagramSocket!=null&&!datagramSocket.isClosed())
{
datagramSocket.isClosed();
}
try {
port=Integer.parseInt(JOptionPane.showInputDialog(this,"请输入要监听的端口号","端口号",JOptionPane.QUESTION_MESSAGE));
if(port<1||port>65535)
{
thrownew RuntimeException("端口号超出范围");
}
}catch(Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(GuiChat.this,"你输入的端口号不正确,请输入1~65535之间的数");
continue;
}
datagramSocket=new DatagramSocket(port);
startListen();
stateLB.setText("已在"+port+"端口监听");
break;
}catch(Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(GuiChat.this,"端口号已被占用,请重新设置端口");
stateLB.setText("当前还未启动监听");
}
}
}
publicvoid startListen(){
new Thread(){
private DatagramPacketp;
@Override
publicvoid run() {
// TODO Auto-generated method stub
byte [] buf=newbyte[1024];
p=new DatagramPacket(buf,buf.length);
while(!datagramSocket.isClosed())
{
try {
datagramSocket.receive(p);
centerTextArea.append(p.getAddress().getHostAddress()+":"
+((InetSocketAddress)
p.getSocketAddress()).getPort()+"对我说:\n"
+new String(p.getData(),0,p.getLength())+"\n\n");
centerTextArea.setCaretPosition(centerTextArea.getText().length());
}catch(Exception e) {
// TODO: handle exception
}
}
}
}.start();
}
}
启动程序 客户端的端口号不能相同,且必须两个端口互为监听才能保证通话
publicclassCreatGUI{
publicstatic void main(String[] args) {
GuiChat ch=new GuiChat();
ch.setUpUI();
ch.initSocket();
ch.setListener();
}
}