关于Java的UDP通信连接实现
2015-10-14 16:39
633 查看
知识点:
1.关于TCP与UDP的主要区别:TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快.
2.关于InetAddress的用法:
IP地址是IP使用的32位(IPv4)或者128位(IPv6)位无符号数字,它是传输层协议TCP,UDP的基础。InetAddress是Java 对IP地址的封装,在java.net中有许多类都使用到了InetAddress,包括 ServerSocket,Socket,DatagramSocket等等。
InetAddress的实例对象包含以数字形式保存的 IP地址,同时还可能包含主机名(如果使用主机名来获取InetAddress的实例,或者使用数字来构造,并且启用了反向主机名解析的功能)。 InetAddress类提供了将主机名解析为IP地址(或反之)的方法。
InetAddress对域名进行解析是使用本地机器配置或者网络命名服务(如域名系统(Domain Name System,DNS)和网络信息服务(Network Information Service,NIS))来实现。对于DNS来说,本地需要向DNS服务器发送查询的请求,然后服务器根据一系列的操作,返回对应的IP地址,为了提高效率,通常本地会缓存一些主机名与IP地址的映射,这样访问相同的地址,就不需要重复发送DNS请求了。在java.net.InetAddress类同样采用了这种策略。在默认情况下,会缓存一段有限时间的映射,对于主机名解析不成功的结果,会缓存非常短的时间(10秒)来提高性能。
3.Java中的DatagramPacket与DatagramSocket的初步
DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送数据报的套接字
代码实现
1.构建UDP服务器
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * * @author Administrator */ public class EchoUDPServer { private int port=6666; private DatagramSocket socket; public EchoUDPServer() throws IOException{ socket =new DatagramSocket(port); System.out.println("UDP服务器已启动....."); } public String echo(String msg){ return "server :"+msg; } public void service(){ while(true){ try{ DatagramPacket packet =new DatagramPacket(new byte[512],512); socket.receive(packet); String msg = new String(packet.getData(),0,packet.getLength(),"GB2312"); System.out.println(packet.getAddress()+" : "+packet.getPort()+">"+msg); packet.setData(echo(msg).getBytes("GB2312")); socket.send(packet); }catch(IOException e){ System.out.println(e); } } } public static void main(String args[])throws IOException{ new EchoUDPServer().service(); } }
2.UDP客户端
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * * @author Administrator */ public class EchoUDPClient { private int remotePort; private InetAddress remoteIP; private DatagramSocket socket; //UDP套接字 public EchoUDPClient(String ip,String port)throws IOException{ this.remotePort=Integer.parseInt(port); this.remoteIP=InetAddress.getByName(ip); //创建一个UDP套接字,与本地任意一个未使用的UDP端口绑定 socket=new DatagramSocket(); //与本地一个固定的UDP端口绑定 // socket=new DatagramSocket(9000); } //定义一个数据的发送方法。 public void send(String msg){ try { //先准备一个待发送的数据报 byte[] outputData=msg.getBytes("GB2312"); //构建一个数据报文。 DatagramPacket outputPacket=new DatagramPacket(outputData, outputData.length,remoteIP,remotePort); //给EchoUDPServer发送数据报 socket.send(outputPacket); //给EchoUDPServer发送数据报 } catch (IOException ex) { } } //定义一个数据的接收方法。 public String receive(){//throws IOException{ String msg; //先准备一个空数据报文 DatagramPacket inputPacket=new DatagramPacket(new byte[512],512); try { //阻塞语句,有数据就装包,以装完或装满为此. socket.receive(inputPacket); //从报文中取出字节数据并装饰成字符。 msg=new String(inputPacket.getData(), 0,inputPacket.getLength(),"GB2312"); } catch (IOException ex) { msg=null; } return msg; } public void close(){ if(socket!=null) socket.close();//释放本地端口. } }
3.用户界面
代码:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package udp; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Administrator */ public class EchoUDPClinetFrame extends javax.swing.JFrame { private EchoUDPClient ec; private String msg; /** * Creates new form IOJFrame */ public EchoUDPClinetFrame() throws IOException { initComponents(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jLabel1 = new javax.swing.JLabel(); jTextField1 = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); jTextField2 = new javax.swing.JTextField(); jButton2 = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); jScrollPane2 = new javax.swing.JScrollPane(); jTextArea2 = new javax.swing.JTextArea(); jButton3 = new javax.swing.JButton(); jButton4 = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jLabel1.setText("IP地址"); jTextField1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField1ActionPerformed(evt); } }); jLabel2.setText("端口"); jTextField2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField2ActionPerformed(evt); } }); jButton2.setText("连接"); jButton2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); jTextArea1.setEditable(false); jTextArea1.setColumns(20); jTextArea1.setRows(5); jTextArea1.addCaretListener(new javax.swing.event.CaretListener() { public void caretUpdate(javax.swing.event.CaretEvent evt) { jTextArea1CaretUpdate(evt); } }); jTextArea1.addAncestorListener(new javax.swing.event.AncestorListener() { public void ancestorMoved(javax.swing.event.AncestorEvent evt) { } public void ancestorAdded(javax.swing.event.AncestorEvent evt) { jTextArea1AncestorAdded(evt); } public void ancestorRemoved(javax.swing.event.AncestorEvent evt) { } }); jScrollPane1.setViewportView(jTextArea1); jLabel3.setText("信息显示区"); jLabel4.setText("信息录入区"); jScrollPane2.setAutoscrolls(true); jTextArea2.setColumns(20); jTextArea2.setRows(5); jTextArea2.setAutoscrolls(false); jScrollPane2.setViewportView(jTextArea2); jButton3.setText("发送"); jButton3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton3ActionPerformed(evt); } }); jButton4.setText("退出"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 121, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 467, Short.MAX_VALUE) .addComponent(jLabel3) .addComponent(jLabel4) .addComponent(jScrollPane2)) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(jButton3) .addGap(38, 38, 38) .addComponent(jButton4))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2) .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButton2)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel3) .addGap(8, 8, 8) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 27, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton3) .addComponent(jButton4)) .addGap(22, 22, 22)) ); pack(); }// </editor-fold> private void jTextField2ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: //发送按钮 msg=jTextArea2.getText(); jTextArea1.append("已发送 : "+msg+"\n"); jTextArea2.setText(null); try { ec.send(msg);//发送一串字符。 } catch (Exception ex) { Logger.getLogger(EchoUDPClinetFrame.class.getName()).log(Level.SEVERE, null, ex); } } private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: //连接按钮 String ip; String port; if(!jTextField1.getText().equals("")){ ip=jTextField1.getText(); port=jTextField2.getText(); } else{ ip = "222.201.101.15"; port = "6666"; } try { ec=new EchoUDPClient(ip,port); jTextArea1.append("UDP创建成功.\r\n"); Thread receiver = new Thread(){ @Override public void run(){ String msg = null; while(true){ try{ msg = ec.receive(); } catch(Exception ex){ jTextArea1.append("套接字异常关闭"+"\n"); } if(msg!=null){ jTextArea1.append(msg+"\n"); } else{ jTextArea1.append("你的对话已关闭!"+"\n"); break; } } }}; receiver.start(); } catch (IOException ex) { jTextArea1.append("UDP创建失败.\r\n"); } } private void jTextArea1CaretUpdate(javax.swing.event.CaretEvent evt) { // TODO add your handling code her } private void jTextArea1AncestorAdded(javax.swing.event.AncestorEvent evt) { // TODO add your handling code here: } /** * @param args the command line arguments */ public static void main(String args[]) throws IOException { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(EchoUDPClinetFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(EchoUDPClinetFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(EchoUDPClinetFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(EchoUDPClinetFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { try { EchoUDPClinetFrame ioj =new EchoUDPClinetFrame(); ioj.setVisible(true); } catch (IOException ex) { Logger.getLogger(EchoUDPClinetFrame.class.getName()).log(Level.SEVERE, null, ex); } } }); } // Variables declaration - do not modify private javax.swing.JButton jButton2; private javax.swing.JButton jButton3; private javax.swing.JButton jButton4; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTextArea jTextArea1; private javax.swing.JTextArea jTextArea2; private javax.swing.JTextField jTextField1; private javax.swing.JTextField jTextField2; // End of variables declaration }
相关文章推荐
- Eclipse 选择真机调试。
- Spring中配置和读取多个Properties文件
- eclipse 响应慢 或 未响应
- java 对象的存储形式
- Java并发之ThreadPoolExecutor和FutureTask
- 关于Java集合的小抄
- 关于JAVA继承、多态、抽象类、接口等性质的学习(3)
- java HashMap原理
- java集群技术
- java编程思想-复用类
- springMVC 请求404异常或静态资源无法访问
- Java 反射
- 浅析Java中的final关键字
- springmvc学习中~~
- 初识JAVA(二)(送给Java和安卓初学者)----常见错误
- java多线程学习笔记(五) ——死锁与饿汉式懒汉式
- java中HashMap遍历方法
- java二维码生成工具
- java记——关于溢出
- java中值传递和引用传递