- 浏览: 327222 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 6733UDP发送数据报 作者:legend QQ:158 ... -
使用PropertyChangeSupport监控变量
2011-02-08 00:27 10161使用PropertyChangeSuppor ... -
UDP广播与多播简单实现
2011-02-04 18:47 74930UDP广播与多播 作者:legend QQ:1580675 ... -
UDP初步
2011-02-04 17:38 2335UDP初步 作者:Legend QQ:158067 ... -
随笔--结束与新的开始
2011-02-04 17:31 1726很久没有写博客了,最近确实很忙,时间飞逝,转眼已大四,很快就要 ...
相关推荐
UDP使用地址“255.255.255.255”进行局域网广播,定时每10秒发送一次数据报,数据包内容为当前电脑的日期和时间
易语言UDP数据报服务源码,UDP数据报服务,启动新线程,子程序2,Bind,Close,Sendto,Recvfrom,Socket_WSAStartup,Socket_WSACleanup,Socket_UDP,Socket_Bind,Socket_接收数据报,Socket_发送数据报,WSASetLastError,...
基于winpcap开发的UDP网卡数据捕获实例,主要功能包括:1.自动选择本机IP地址的网络适配器进行网络数据捕获; 2.具有筛选IP地址、端口、协议、方向功能; 3.具有UDP数据报正文提取功能。
利用UdpClient进行Udp通信,进行简单收发数据.VS2010打开
C# UDP通信报错:远程主机强迫关闭了一个现有的连接。 是windows的一个bug,在linux下没有这个bug。 将代码加入程序即可解决
UDP收数据系统结构:UDP收数据======窗口程序集1||||------__启动窗口_创建完毕||||------_数据报2_数据到达||||------_按钮1_被单击======窗口程序集1||||------__启动窗口_创建完毕||||------_数据报2_数
线程通信程序,开启线程后可以接收来自UDP协议发送的数据报
UDP是面向非连接的,UDP传输的是数据报只负责传输信息,不保证信息一定收到,虽然安全性不如TCP(面向连接、用Socket进行通信),但是性能较好。 从简单到复杂,首先简单介绍一下怎么利用UDP实现客服端发送消息给...
#从给定的端口,从任何发送者,接收UDP数据报 s.bind((,port)) print 'waiting on port:',port while True: data,addr = s.recvfrom(1024) #接收一个数据报(最大到1024字节) print 'reciveed:',
信息简介:UDP协议,即拥护数据报协议(Use Datagram Protocol).是一个简单的面向数据报的传输层协议.他不提供可靠性,即只把应用程序传给IP层的数据发送出去,但是并不能保证他们能到达目的.广播和多播是基于UDP协议的两...
一个简单的电子应用程序,用于创建 UDP 客户端和服务器以发送和接收数据报。 您可以在任何主机和端口上添加 N 个 UDP 客户端,在任何主机和端口上添加 N 个 UDP 服务器。 您还可以生成随机数据并以固定时间间隔从...
UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。
用户数据报UDP有两个字段:数据字段和首部字段。首部字段只有8个字节,由四个字段组成,每个字段的长度都是两个字节。各字段意义如下: (1)源端口:源端口号,在需要对方回信时选用,不需要时可用全0 (2)目的端口:...
UDP是轻量的、不可靠的、面向数据报、无连接的协议,它可以用于对可靠性要求不高的场合,和TCP通信不同,两个程序之间进行UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。...
UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。 UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的...
在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。这里我们还要了解一个名词Socket,也就是常说的“套接字”。 Socket简单地说,就是一个IP地址加一个port端口。因为我们要传输数据,就要知道往...
UDP单播,发送与接收(代码)详细介绍。单播流程:主机A向主机B发送UDP数据报,发送的目的IP为192.168.1.151,端口为 80,此数据经过UDP层、IP层,到达数据链路层,数据在整个以太网上传播。