- 浏览: 329223 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jnssvh:
楼主,还发代码吗?jnssvh@aliyun.com
SurfaceView简单例子 -
hou_anne:
讲解的非常详细
Android TabActivity实现多页显示效果 -
小鱼小鹰:
现在还能吗。。。296252344@qq.com
自定义控件(SurfaceView与view结合) -
flyar:
你好!我按照你的代码实现多点广播,但是在一台机子休眠,另一台手 ...
UDP广播与多播简单实现 -
herber2010:
图有错误~~
java实现快速排序
UDP接收数据报
作者:legend
QQ:158067568
对于接受udp数据包,可以有如下另种设计:
第一,同UDP发送端一样,写成一个助手类,然后每次将收到的结果给需要的地方。
另一种是,将udp接收端与其处理程序写在同一个类中,即其受到数据之后就进行分析,然后做出判断与处理。
分析
对于本应用程序来说,我才去了第二中方法。首先,该udp接收端是在应用程序实例化是就存在,直到应用程序死亡期结束生命。那么从始至终我们只需要一个udp接受端。其次在设计udp接收端是,其接受的数据主要是字符串,对字符串做出相应处理的时间一般不会太长。而且UDP接收端接收到数据后要做出相应的操作,而且多数会用到调用它的类的相关方法。
实现
前面已将分析了,UDP接收端接收到数据后要做出相应的操作,而且多数会用到调用它的类的相关方法。所以udp接收端在实例化的时候,需要知道调用它的类的引用。
其次,接收端为阻塞方法,其应该单写在一个线程中。
代码实现
package cn.edu.heut.zcl; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JOptionPane; import cn.edu.heut.helper.UDPSendHelper; import cn.edu.heut.zcl.domain.UserInfo; import cn.edu.heut.zcl.rtp.capture.AudioCapture; import static cn.edu.heut.zcl.Constant.*; /** * 该类主要是一直循环等待着其他客户端发来的消息,监听端口是19881 * 发送端将采用广播的形式进行发送。 * @author zcl * */ public class UDPReceiveSystemInfo extends Thread{ /** * 大管家的引用 */ private Master master ; /** * 接收者的套接字 */ private DatagramSocket receiveSocket ; private DatagramPacket receiveDatagramPacket ; public UDPReceiveSystemInfo(Master master){ this.master = master ; } @Override public void run() { try { receiveSocket = new DatagramSocket(UDPRECEIVESYSTEMINFO_UDP_RECEIVE_PORT); } catch (SocketException e) { e.printStackTrace(); } while(master.isLive()){//如果程序还在运行,那么就一直循环监听 receiveDatagramPacket = new DatagramPacket( new byte[UDPRECEIVESYSTEMINFO_UDP_RECEIVE_DP_LENGTH],UDPRECEIVESYSTEMINFO_UDP_RECEIVE_DP_LENGTH); try {//此处接收发送来的数据报文 receiveSocket.receive(receiveDatagramPacket); executeReceiveData(receiveDatagramPacket); } catch (IOException e) { e.printStackTrace(); } } if(!master.isLive()){ receiveSocket.close(); } } /** * 处理发送来的数据 * @param 发送来的数据 */ public void executeReceiveData(DatagramPacket receiveDP){ String receiveData = new String(receiveDP.getData()).trim();//得到发送过来的数据 String ipAddress = receiveDP.getAddress().getHostAddress(); // System.out.println("ipAddress:::::::: "+ipAddress); if(receiveData.startsWith(CONTROL_MSG_ADD_A_CLIENT)){//如果是新添加一个客户端,执行以下操作 String name = findUserName(receiveData); //将该客户端的信息添加到记录当前在线用户的list中 UserInfo newUser = new UserInfo(); newUser.setUserName(name); newUser.setUserIP(receiveDP.getAddress()); master.currentOnLineUserList.add(newUser); //在PhoneFrame的表格中添加该客户端信息。 String[] rowData = {name,ipAddress}; master.phoneFrame.defaultTableModel.addRow(rowData); String localHostIP = null; try { localHostIP = InetAddress.getLocalHost().toString(); } catch (UnknownHostException e) { e.printStackTrace(); } //如果不是自己的话,之后再告诉这个新加入的客户端,我是谁,我的相关信息 if(!master.getUserName().equals(name) && !ipAddress.equals(localHostIP)){ String data = CONTROL_MSG_ADD_A_CLIENT_ECHO_INFO +CONTROL_MSG_USER_NAEM +master.getUserName() + CONTROL_MSG_END_USER_NAEM; InetAddress destIPAddress = null; destIPAddress = receiveDP.getAddress(); int destPort = UDPRECEIVESYSTEMINFO_UDP_RECEIVE_PORT; new UDPSendHelper(data, destIPAddress, destPort).start(); } }else if(receiveData.startsWith(CONTROL_MSG_LEAVE_THE_CLIENT)){//收到退出一个客户端,执行以下方法 // System.out.println(receiveData); String name = findUserName(receiveData); //将list中的该用户删除 for(int i=0 ;i<master.currentOnLineUserList.size();i++){ UserInfo ui = master.currentOnLineUserList.get(i); String uiName = ui.getUserName(); InetAddress uiIp = ui.getUserIP() ; if(uiName.equals(name) && uiIp.toString().equals(ipAddress)){//判断是否是同一个用户,删除该项,退出循环 master.currentOnLineUserList.remove(i); break; } } //将PhoneFrame表格中的信息删除 for(int i=0 ;i<master.phoneFrame.defaultTableModel.getRowCount();i++){//进行行遍历 String curTabUserName = (String) master.phoneFrame.defaultTableModel.getValueAt(i, 0); String curTabUserIP = (String) master.phoneFrame.defaultTableModel.getValueAt(i, 1); if(curTabUserName.equals(name) && curTabUserIP.equals(ipAddress)){ master.phoneFrame.defaultTableModel.removeRow(i); break; } } }else if(receiveData.startsWith(CONTROL_MSG_ADD_A_CLIENT_ECHO_INFO)){//如果是收到了该客户端发送给其他服务器的新添加一个客户端的回复信息,则根据回复信息,将该发送者信息添加入list,并且在表格中显示。 String name = findUserName(receiveData); //将该客户端的信息添加到记录当前在线用户的list中 UserInfo newUser = new UserInfo(); newUser.setUserName(name); newUser.setUserIP(receiveDP.getAddress()); master.currentOnLineUserList.add(newUser); //在PhoneFrame的表格中添加该客户端信息。 String[] rowData = {name,ipAddress}; master.phoneFrame.defaultTableModel.addRow(rowData); }else if(receiveData.startsWith(CONTROL_MSG_CONNECT_VOICE_REQUEST)){//如果收到的进行语音通讯请求,执行以下内容 if(!master.connectState.isConnecting()){//如果当前客户端没有通话,则执行以下操作 System.out.println("receiveData request:"+receiveDP.getAddress().toString()); int conJOP =JOptionPane.showConfirmDialog(null,ipAddress+"的来电,是否接听", "来电", JOptionPane.YES_NO_OPTION); InetAddress destAddress = receiveDP.getAddress(); int destPort = UDPRECEIVESYSTEMINFO_UDP_RECEIVE_PORT; switch(conJOP){ case 0://接听来电 String acceptData = CONTROL_MSG_CONNECT_VOICE_ACCEPT; new UDPSendHelper(acceptData, destAddress, destPort).start(); master.connectState.setConnecting(true);//设置当前连接为通话状态 //do something... // new AudioCapture(master,ipAddress).start(); String port = RTP_CALLER_RECEIVE_VOICE_PORT; new Thread(new AudioCapture(master,ipAddress,port)).start();//开启通话线程开始通话 break; case 1://拒绝来电 String refuseData = CONTROL_MSG_CONNECT_VOICE_REFUSE; new UDPSendHelper(refuseData, destAddress, destPort).start(); break; } }else{//如果当前客户端正在通话,则执行如下操作:告诉请求方,我正在通话,等会再打过来 String sendConnectingDate = CONTROL_MSG_STATE_CONNECTING; InetAddress destAddress = receiveDP.getAddress(); int destPort = UDPRECEIVESYSTEMINFO_UDP_RECEIVE_PORT; new UDPSendHelper(sendConnectingDate, destAddress, destPort).start(); } }else if(receiveData.startsWith(CONTROL_MSG_CONNECT_VOICE_ACCEPT)){//刚刚发送的请求被接受。此为主叫方 //do something... String port = RTP_CALLER_SEND_VOICE_PORT; new Thread(new AudioCapture(master,ipAddress,port)).start();//开启通话线程开始通话 System.out.println("执行通话操作.."); }else if(receiveData.startsWith(CONTROL_MSG_CONNECT_VOICE_REFUSE) ){//刚刚发送的请求被拒绝 JOptionPane.showConfirmDialog(null,ipAddress+"拒绝您的来电", "拒绝来电", JOptionPane.YES_OPTION); }else if( receiveData.startsWith(CONTROL_MSG_STATE_CONNECTING)){//对方正在通话中,执行如下操作 JOptionPane.showConfirmDialog(null,ipAddress+"正在通话中,请稍后再拨", "提示", JOptionPane.YES_OPTION); } } /** * 从字符串str中寻找用户的用户名,如果存在返回用户名,不存在返回null。 * -用户名是包裹在名字控制字符中间的字符串。 * @param str * @return uName 返回用户名 */ public String findUserName(String str){ String uName = null ; String msg =findFirstPatternString(CONTROL_MSG_USER_NAEM+"{1}.*"+CONTROL_MSG_END_USER_NAEM+"{1}", str); uName = msg.substring(CONTROL_MSG_USER_NAEM.length(), msg.length()-CONTROL_MSG_END_USER_NAEM.length());//此处得到用户名字 return uName; } /** * 查询msg中是否存在符合patternString的字符串,如果有返回第一个出现该字符串的数据,不存在返回null * @param patternString 匹配字符串 * @param msg 查询字符串 * @return 结果 */ public static String findFirstPatternString(String patternString,String msg){ String result = null ; Pattern p = Pattern.compile(patternString); Matcher m = p.matcher(msg); if(m.find()){ result = m.group(); } return result; } }
以上是udp接收端的代码,一种会有一些类暂时还没有给出,在之后会介绍到。代码也会随程序中其他代码一起给出。
发表评论
-
UDP发送数据报
2011-02-11 15:29 6762UDP发送数据报 作者:legend QQ:158 ... -
使用PropertyChangeSupport监控变量
2011-02-08 00:27 10212使用PropertyChangeSuppor ... -
UDP广播与多播简单实现
2011-02-04 18:47 75039UDP广播与多播 作者:legend QQ:1580675 ... -
UDP初步
2011-02-04 17:38 2369UDP初步 作者:Legend QQ:158067 ... -
随笔--结束与新的开始
2011-02-04 17:31 1759很久没有写博客了,最近确实很忙,时间飞逝,转眼已大四,很快就要 ...
相关推荐
在本文中,我们将深入探讨如何在STM32F107VCT6微控制器上实现基于W5500硬件协议栈的UDP(用户数据报协议)收发数据。W5500是一款集成TCP/IP协议栈的以太网控制器,它提供了全硬件的网络接口,简化了嵌入式系统的网络...
2. 接收数据:接收方根据接收到的UDP数据报的端口号,将数据交给相应的应用程序。由于UDP是无连接的,所以接收方无法确认数据是否丢失或重复,应用程序需要自行处理这些问题。 TCP与UDP的选择取决于应用需求。TCP...
本篇文章将详细讲解如何使用MATLAB实现UDP广播数据报,以及涉及的相关知识点。 首先,我们要理解UDP的基本概念。UDP是一种不可靠的传输协议,它不保证数据包的顺序、可靠性和完整性,但因其轻量级的特性,具有较低...
### UDP用户数据报协议知识点详解 #### 一、UDP简介 用户数据报协议(User Datagram Protocol,简称UDP)是一种在OSI参考模型中处于传输层的无连接协议,它提供了面向事务的简单不可靠信息传送服务。UDP并不保证...
在本文中,我们将深入探讨如何在C#中使用UDP(用户数据报协议)进行socket编程,以便收发数据。UDP是一种无连接的、不可靠的传输层协议,它提供了较低的延迟和较高的吞吐量,适合实时数据传输或对顺序传输要求不高的...
以上就是一个基本的C++ UDP接收程序的框架。为了进一步扩展功能,可以添加多线程或异步处理,以同时处理多个数据报。此外,考虑到跨平台性,可以使用如Boost.Asio这样的库,它提供了一种更高级别的接口,简化了网络...
在本文中,我们将深入探讨如何利用 Netty 4 构建基于 UDP(用户数据报协议)的数据接收服务,以及如何实现相应的发送服务。 首先,UDP 是一种无连接的传输层协议,它不保证数据的顺序或可靠性,但具有较低的开销,...
在这些应用中,网络通信是必不可少的一环,而UDP(用户数据报协议)作为一种无连接的传输层协议,因其轻量级、高效性而常被用于实时性要求较高的场景。本实验将详细介绍如何在STM32F407上实现UDP客户端的数据收发。 ...
UdpClient用于发送和接收数据报,而UdpServer则用于监听和响应数据报。由于UDP没有连接的概念,所以数据的顺序和完整性无法保证,但其快速的传输特性使得它在某些应用场景中不可或缺。 对于组播,TCP不支持,而UDP...
Java UDP(用户数据报协议)收发结构体实例与Socket编程是网络通信中的重要主题,尤其是在需要高效、无连接的数据传输场景下。UDP是一种无连接的传输层协议,相较于TCP,它提供了更低的延迟和更高的吞吐量,但不保证...
在编程领域,尤其是在网络通信中,UDP(User Datagram Protocol,用户数据报协议)是一种无连接的、不可靠的传输协议,常用于实时音频、视频流等对数据完整性要求不高的场景。C#作为.NET框架的主要编程语言,提供了...
STM32 UDP通讯接收发送源程序是针对STM32F407微控制器设计的通信程序,主要利用了网络协议栈中的用户数据报协议(UDP)进行数据传输。该程序适用于嵌入式硬件开发,特别是在需要稳定网络通信的场景下。下面将详细...
Delphi是一款强大的Windows应用程序开发工具,它提供了丰富的组件库和编程接口,使得网络编程变得相对简单,尤其是UDP(用户数据报协议)通信。 UDP是一种无连接的、不可靠的传输层协议,它不保证数据的顺序或完整...
QUdpSocket用于处理UDP的收发操作,而QTimer则可以设置定时器来定期发送数据报。 1. **创建QUdpSocket对象**: 在项目中,我们首先需要创建一个QUdpSocket实例,通过它来发送和接收UDP数据包。确保在构造函数或者...
易语言UDP数据报服务源码,UDP数据报服务,启动新线程,子程序2,Bind,Close,Sendto,Recvfrom,Socket_WSAStartup,Socket_WSACleanup,Socket_UDP,Socket_Bind,Socket_接收数据报,Socket_发送数据报,WSASetLastError,...
在编程领域,网络通信是不可或缺的一部分,而C#作为.NET框架的主要编程语言,提供了丰富的库来支持各种网络通信协议,包括UDP(用户数据报协议)。本文将深入探讨C#中如何实现UDP的异步发送和接收,这对于构建实时、...
在Unix-like系统和Windows上,socket API提供了创建、绑定、发送和接收UDP数据报的方法。下面是一些关键步骤: 1. **创建Socket**:使用`socket()`函数创建一个UDP套接字,指定`SOCK_DGRAM`类型,因为UDP是数据报...
另一个文件"UDP_数据报"可能是一个包含了实际实现UDP通信的源代码文件,可能是.cpp或.h格式,包含了发送和接收UDP数据报的函数和逻辑。 在UDP通信中,关键知识点包括: 1. **UDP协议基础**:理解UDP的基本特性,如...
在UDP协议中,数据是以数据报的形式传输的。每个数据报包含完整的源地址和目的地址,以及数据本身,这样就可以独立于其他数据报进行路由。由于UDP是无序的,所以数据报可能会以任意顺序到达目的地,而且可能会丢失...