Java Udp通讯程序

最近在写嵌入式通讯程序,所以就想用Java写一个Udp通讯的服务端程序来实现,从开发板上发数据包到PC,PC上的服务端程序解析数据,以前写的Java程序比较少,所以就写了一个Java的Udp的Server和Client集一体的通讯程序,现把代码列出,还有不足之处,请各位高手指点。

 

/*主函数 udpmain.java*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jappudp;

/**
 *
 * @author AlimysoYang
 */
public class udpmain {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
      udpframe uf = new udpframe();
    }

}

 

/*主窗口、实现程序 udpframe.java*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jappudp;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.lang.*;
import java.util.Date;
import java.text.SimpleDateFormat;

/**
 *
 * @author AlimysoYang
 */
public class udpframe extends JFrame implements Runnable,ActionListener{
  private Thread rthread = null;
  //初始化窗口控件
  private JLabel lbRecvPort = new JLabel("接收端口",JLabel.LEFT);
  private JLabel lbSendIP = new JLabel("发送IP",JLabel.LEFT);
  private JLabel lbSendPort = new JLabel("发送端口",JLabel.LEFT);
  private JLabel lbRecv = new JLabel("接收数据",JLabel.LEFT);
  private JLabel lbSend = new JLabel("发送数据",JLabel.LEFT);
  private JTextField tfRecvPort = new JTextField("8800",6);
  private JTextField tfSendIP = new JTextField("127.0.0.1",15);
  private JTextField tfSendPort = new JTextField("8801",6);
  private JTextArea taRecv = new JTextArea();
  private JTextArea taSend = new JTextArea();
  private JButton btnConnect = new JButton("连接");
  private JButton btnDisConnect = new JButton("断开连接");
  private JButton btnSend = new JButton("发送");
  private JCheckBox cbHex = new JCheckBox("16进制",false);
  private JPanel plTop = new JPanel(new FlowLayout(FlowLayout.LEFT));
  private JPanel plBottom = new JPanel(new FlowLayout(FlowLayout.LEFT));
  private JScrollPane spRecv = new JScrollPane(taRecv);
  private JScrollPane spSend = new JScrollPane(taSend);
  private GridBagLayout mgbLayout = new GridBagLayout();
  private GridBagConstraints mgbConstraints = new GridBagConstraints();

  private int sPort,rPort;
  private String sHost;
  private DatagramSocket sUdp = null;
  private DatagramSocket rUdp = null;
  private DatagramPacket sPacket,rPacket;
  private byte[] sBuffer = null;
  private byte[] rBuffer = null;
  private SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 

//构造函数,实现窗口布局

  public udpframe()
  {
    InitComponents();
  }

//重构线程start函数

  public void start()
  {
    if (rthread==null)
    {
      rthread = new Thread(this);
      rthread.start();
    }
  }

//重构线程stop函数

  public void stop()
  {
    rthread = null;
  }
  //线程run函数,主要实现对指定端口的数据接收
  public void run()
  {
    Thread cthread = Thread.currentThread();
    while (cthread==rthread)
    {
      RecvData();
      /*try
      {
        rthread.sleep(1000);
      }catch(InterruptedException ie)
      {
        System.out.println(ie);
      }*/
    }
  }
 
  private void setMainLayout(int gridx,int gridy,int gridwidth,int gridheight,int weightx,int weighty,int fill)
  {
    mgbConstraints.gridx = gridx;
    mgbConstraints.gridy = gridy;
    mgbConstraints.gridwidth = gridwidth;
    mgbConstraints.gridheight = gridheight;
    mgbConstraints.weightx = weightx;
    mgbConstraints.weighty = weighty;
    mgbConstraints.fill = fill;
  }
  //初始化窗口布局
  private void InitComponents()
  {
    plTop.add(lbRecvPort);
    plTop.add(tfRecvPort);
    plTop.add(lbSendIP);
    plTop.add(tfSendIP);
    plTop.add(lbSendPort);
    plTop.add(tfSendPort);
    plTop.add(btnConnect);
    plTop.add(btnDisConnect);
    plTop.add(cbHex);

    this.getContentPane().setLayout(mgbLayout);
    setMainLayout(0,0,1,1,100,2,GridBagConstraints.BOTH);
    mgbLayout.setConstraints(plTop, mgbConstraints);
    getContentPane().add(plTop);

    setMainLayout(0,1,1,1,100,2,GridBagConstraints.BOTH);
    mgbLayout.setConstraints(lbRecv, mgbConstraints);
    getContentPane().add(lbRecv);

    setMainLayout(0,2,1,1,100,46,GridBagConstraints.BOTH);
    mgbLayout.setConstraints(spRecv, mgbConstraints);
    getContentPane().add(spRecv);

    setMainLayout(0,3,1,1,100,2,GridBagConstraints.BOTH);
    mgbLayout.setConstraints(lbSend, mgbConstraints);
    getContentPane().add(lbSend);

    setMainLayout(0,4,1,1,100,46,GridBagConstraints.BOTH);
    mgbLayout.setConstraints(spSend, mgbConstraints);
    getContentPane().add(spSend);

    plBottom.add(btnSend);
    setMainLayout(0,5,1,1,100,2,GridBagConstraints.BOTH);
    mgbLayout.setConstraints(plBottom,mgbConstraints);
    getContentPane().add(plBottom);

    btnDisConnect.setEnabled(false);

    btnConnect.addActionListener(this);
    btnDisConnect.addActionListener(this);
    btnSend.addActionListener(this);

    this.setTitle("UDP(for NetBeans) v1.00");
    this.setSize(800,600);
    this.setResizable(true);
    SrceenCenter();
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
  }

//布局窗口在屏幕居中

  private void SrceenCenter()
  {
    Toolkit tkit = Toolkit.getDefaultToolkit();
    Dimension screensize = tkit.getScreenSize();
    Dimension framesize = this.getSize();
    this.setLocation((screensize.width - framesize.width) / 2, (screensize.height - framesize.height) / 2);
  }

//发送数据

  private void SendData(String Data)
  {
    try
    {
      if (sUdp==null)
        sUdp = new DatagramSocket();
      sHost = tfSendIP.getText().trim();
      sPort = Integer.parseInt(tfSendPort.getText().trim());
      sBuffer = new byte[1024];
      if (cbHex.isSelected())
      {
        SendHexData(Data);
      }
      else
      {
        sBuffer = Data.getBytes();
      }
      sPacket = new DatagramPacket(sBuffer,sBuffer.length,InetAddress.getByName(sHost),sPort);
      sUdp.send(sPacket);
      sUdp.close();
      sUdp = null;
    }catch(IOException e)
    {
      sUdp.close();
      sUdp = null;
      System.out.println("数据发送错误:" + e);
    }
  }
  //判断字符是否是16进制中的字符
  private boolean CharInRange(char c)
  {
    boolean r = false;
    if ((c>='0') && (c<='9'))
      r = true;
    if ((c>='a') && (c<='f'))
      r = true;
    if ((c>='A') && (c<='F'))
      r = true;
   
    return r;
  }

//把16进制字符串转成字节

  private byte StrToByte(String s)
  {
    /*byte rb;
    int i = Integer.parseInt(s, 16);
    String rs = String.valueOf(i);
    rb = Integer.valueOf(String.valueOf(Integer.parseInt(s, 16))).byteValue();
    return rb;*/
    return Integer.valueOf(String.valueOf(Integer.parseInt(s, 16))).byteValue();
  }
  //发送16进制数据
  private void SendHexData(String Data)
  {
    //sBuffer = new byte[1024];
    int datalen = Data.getBytes().length;
    int i = 0,j = 0;
    while (i<datalen)
    {
      while ((i>=0) && (!CharInRange(Data.charAt(i))))
      {
        i++;
      }
     
      if (((i + 1)>datalen) || (!CharInRange(Data.charAt(i + 1))))
      {
        sBuffer[j] = StrToByte(String.valueOf(Data.charAt(i)));
        j++;
      }
      else
      {
        sBuffer[j] = StrToByte(Data.substring(i, i + 2));
        j++;
      }

      i += 2;
    }
  }

//接收数据

  private void RecvData()
  {
    try
    {
      String recvData;
      rUdp.receive(rPacket);
      if (cbHex.isSelected())
        recvData = RecvHexData();
      else
        recvData = new String(rPacket.getData()).trim();
      recvData = "[" + rPacket.getAddress().getHostAddress() + ":" +
              String.valueOf(rPacket.getPort()) + " // " +
              df.format(new Date()) + "] " + recvData;
      taRecv.append(recvData + "/n");
    }catch(IOException e)
    {
      System.out.println(e);
    }
  }

//接收端连接

  private void Connect()
  {
    try
    {
      rPort = Integer.parseInt(tfRecvPort.getText().trim());
      if (rUdp==null)
        rUdp = new DatagramSocket(rPort);
      btnConnect.setEnabled(false);
      btnDisConnect.setEnabled(true);
      rBuffer = new byte[1024];
      rPacket = new DatagramPacket(rBuffer,rBuffer.length);
      start();
    }catch(SocketException e)
    {
      DisConnect();
      System.out.println("发送端连接失败:" + e);
    }
  }

//接收端断开

  private void DisConnect()
  {
    if (rUdp!=null)
    {
      rUdp.close();
      rUdp = null;
    }
    stop();
    btnConnect.setEnabled(true);
    btnDisConnect.setEnabled(false);
  }

//接收16进制数据

  private String RecvHexData()
  {
    StringBuffer sb = new StringBuffer(rBuffer.length);
    String rHex = "";
    int i;
    for (i = 0;i<rBuffer.length;i++)
    {
      rHex = Integer.toHexString(rBuffer[i] & 0xFF);
      if (rHex.length()==1)
        rHex = '0' + rHex;
      sb.append(rHex.toUpperCase());
    }
    return sb.toString().trim();
  }
 
  public void actionPerformed(ActionEvent e)
  {
    Object source = e.getSource();
    if (source==btnSend)
    {
      String sMsg = taSend.getText().trim();
      if (!sMsg.equals(""))
        SendData(sMsg);
    }
    else if (source==btnConnect)
    {
      Connect();
    }
    else if (source==btnDisConnect)
    {
      DisConnect();
    }
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值