我是靠谱客的博主 拼搏萝莉,最近开发中收集的这篇文章主要介绍android与PC之间的UDP通信,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

由于这段时间学习了安卓手机端与PC端之间的UDP通信原理,所以就在这里写一写自己的一些心得,我会尽量把自己遇到的难题以及自己的一些感觉写清楚,如果有写的不明朗的地方,还希望多多交流。
在铺上代码之前,我觉得很有将UDP通信的一些函数解释清楚,这样便于读者对之后代码的理解!
UDP和TCP/IP协议一样都是痛通信协议。下面我将简单介绍一下UDP和TCP/IP之间的异同点。
TCP(Transmission Control
Protocol,传输控制协议)是面向连接的协议,也就是说在收发数据之间,双方必须建立可靠的连接,也就是行内术语“三次握手,四次挥手”这里就不作细述,网上有很多资料可查,读者有兴趣的话可以自己去看看。
UDP(User Data Protocol)UDP是一个非连接协议,传输数据之前,源端和终端之间是不建立连接的,简单的抓取来自应用程序的数据,并且将其扔到网络之上。
下面介绍实现安卓与PC之间通信需要的类,并对这些类的作用进行比较详细的叙述
DatagramSocket类:此类表示发送和接送数据的套接字(不明白可以直接跳过)
**简单解释一下DatagramSocket类的构造函数**
DatagramSocket()//构造数据报套接字并将其绑定到本地主机上任何可用的端口
Protected DatagramSocket (DatagramSocketImpl imp1)//创建带有指定DatagramSocketImpl的未绑定的数据报套接字
DatagramSocket(int port)
//创建数据报套接字并将其绑定到本地主机绑定的端口号上
DatagramSocket(int port, InetAddress laddr)//创建数据报套接字并将其绑定到本地指定的IP地址和端口号
DatagramSocket(SocketAddress bindaddr) //创建数据报套接字,并将其绑定到本地指定的套接字地址
**DatagramPacket类的构造函数**
DatagramPacket(byte[] buf, int length) //构造DatagramPacket,并接收长度为length的数据包
DatagramPacket(byte[] buf, int lenght, InetAddress address int port)
//将长度为length的数据包发送到主机上指定端口号
DatagramSocket(byte[] buf, int offset, int lenght, InetAddress address int port)
//
构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号
DatagramPacket(byte[] buf, int offset, int length)
//构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
//构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号
DatagramPacket(byte[] buf, int length, SocketAddress address)
//构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号
**安卓端的源码**
public class MainActivity extends Activity {
***DatagramSocket socket;***
**//在收发信息的过程中只需要创建一个DatagramSocket对象即可**
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
socket = new DatagramSocket(9999);
} catch (SocketException e1) {
e1.printStackTrace();
}
Button btn = (Button) this.findViewById(R.id.sendBtn);
final EditText et = (EditText) this.findViewById(R.id.sendtext); // 为什么要添加final修饰
TextView tv = (TextView) this.findViewById(R.id.receivetext); // 获取文本框的内容
***// 发送信息的函数***
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
*new Thread(new Runnable() {
public void run() {*
**//这里要说明一下在Android通信协议必须要放在线程里面进行**
String str = et.getText().toString();
Log.v("发送", str);
***sendMsg(str);***
//sendMsg函数已经封装好,这里直接拿来用
}
}).start();
}
});
**// 接收信息的函数**
try {
**receiveMsg();
//receiveMsg()函数也已经封装好,这里只需要拿来用即可,要体现java的封装思想**
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 定义发送消息的函数sendMsg()
*/
**public void sendMsg(String msg)** {
Log.v("v", "开始发送");
try {
**socket = new DatagramSocket(9999); //用DatagramSocket创建一个sokcet对象发送数据包,9999是本机的端口号
InetAddress server = InetAddress.getByName("192.168.31.207");
//上面代码的意思是获取本地主机的IP的地址,一般情况下使用InetAddress.getByName("IP")的形式,但是也可以用 getAllName()或者getLocalHost()的形式,得到本地主机的地址
byte data[] = msg.getBytes();
//将字符串转换成字节流,因为底层的传输都是字节传输
DatagramPacket pack = new DatagramPacket(data, data.length, server,
6024); // 创建DatagramPacket 对象数据包,这里的6024是我们要发送信息主机的端口号
socket.send(pack);**
Log.v("f", "发送成功!");
} catch (Exception e) {
Log.v("f", "发送失败!");
e.printStackTrace();
}
}
**public void receiveMsg() throws Exception** {
**// 创建线程,同理,接收信息也要放在线程里面接收**
new Thread(new Runnable() {
public void run() {
if (socket != null) {
try {
String str;
while (true) {
**// 创建一个空的字节数组
byte[] data = new byte[1024];
// 将字节数组和数组的长度传进DatagramPacket 创建的对象里面
DatagramPacket pack2 = new DatagramPacket(data,
data.length);**
Log.v("s", "pack2");
Log.v("s", "开始接收");
**socket.receive(pack2);
// socket对象接收pack包,程序启动的时候,socket会一直处于阻塞状态,直到有信息传输进来**
String ip = pack2.getAddress().getHostAddress();
//这段代码的作用获取发送数据的IP地址
int port = pack2.getPort();
//获取发送数据端的端口号
System.out.println(ip);
System.out.println(port);
str = new String(pack2.getData(), 0, pack2.getLength()); // 将字节数组转化成字符串表现出来
Log.v("s", "接收成功: " + str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}

PC端代码

**public class UDPServe**r{
private SendandRecieveMsg srm;
public void UDPsetFrame(){
srm = new SendandRecieveMsg();
Frame frame = new Frame();
frame.setTitle("QQ");
//设置标题名
frame.setSize(800, 800);
//设置窗体的大小
frame.setLayout(new FlowLayout());
//设置流式布局方式
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//设置可见
TextField tf = new TextField(20);
//创建文本框, 20是指定的列数
Button senBtn = new Button("发送");
//设置发送按钮
TextArea ta = new TextArea(20,30);//创建文本域
frame.add(tf);
//添加进frame窗体里面
frame.add(senBtn);
frame.add(ta);
ActionLis ml = new ActionLis(tf,srm);
//将文本框里面内容传进去
senBtn.addActionListener(ml);//给发送按钮加上监听器
//关闭窗口调用的函数
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
//这个函数的意思就是把整个窗体停用下来
}
});
while(true){
try {
**srm.UDPReceiveMsg(ta);
//接收信息的socket不断接收信息,而且必须要放在最后,不断while会阻断其他程序的进行,UDPReceiveMsg()函数已经封装进SendandRecieveMsg类中**
} catch (SocketException e) {
e.printStackTrace();
}
}
}
public static void main(String[] arrys) throws IOException{
new UDPServer().UDPsetFrame();
//主函数,创建对象并启动
}
**public class ActionLis implements ActionListener**{
private TextField tf;
private SendandRecieveMsg srm;
//构造函数
public ActionLis() {
}
public ActionLis(TextField tf, SendandRecieveMsg srm) {
//构造函数将文本tf和srm传进来
this.tf = tf;
this.srm = srm;
}
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("发送")){
srm.UDPSendMsg(tf.getText().trim());
//发送信息个Android端
System.out.println("发送的内容是:" + tf.getText().trim());
}
}
}
**public class SendandRecieveMsg**{
DatagramSocket socket;
//定义DatagramSocket类对象
public SendandRecieveMsg(){
try {
**socket = new DatagramSocket(6024);
//这里6024是我们PC的程序的端口号**
} catch (SocketException e) {
e.printStackTrace();
}
}
/**
* 定义发送信息函数
*/
**public void UDPSendMsg(String msg)**{
if(socket != null) {
try {
**InetAddress server = InetAddress.getByName("192.168.31.175");
byte data[] = msg.getBytes();
DatagramPacket pack = new DatagramPacket(data, data.length, server, 9999); //这是对方网络软件的端口
socket.send(pack);
//这段代码在Android端已经介绍过,所以在这里就不再详述**
System.out.println("发送成功");
} catch (Exception e) {
System.out.println("发送失败");
e.printStackTrace();
}
}
}
/**
* 定义接收信息函数
*/
**public void UDPReceiveMsg(TextArea ta) throws SocketException**{
String str = null;
while(true) {
//创建字节数组
byte[] data = new byte[100];
//将字节数组和数组的长度传进DatagramPacket里面
DatagramPacket pack1 = new DatagramPacket(data, data.length);
try {
System.out.println("启动");
**//socket对象接收pack包
socket.receive(pack1);
String ip = pack1.getAddress().getHostAddress();
//获取IP地址
int port = pack1.getPort();//这段代码在Android端已经介绍过,所以在这里就不再详述**
str = new String(pack1.getData(), 0, pack1.getLength());
str = ip + ":" + port + ":" + str;
ta.insert(str, pos);
//将消息插到文本里面
if(str.equals("bye")){
socket.close();
//关闭接口
}
} catch (Exception e) {
System.out.println("发生异常");
e.printStackTrace();
}
}
}
}

有什么不对的地方,希望读者可以提出意见,其实只要把了解UDP通信的原理,再将UDP通信的几个函数的用于弄清楚,就会对通信的底层原理理解的更加深刻。

最后

以上就是拼搏萝莉为你收集整理的android与PC之间的UDP通信的全部内容,希望文章能够帮你解决android与PC之间的UDP通信所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部