利用UDP协议进行的Socket编程

UDP网络编程
  • 1.UDP是面向无连接的数据传输、不可靠的,但传输效率高(传输音频啊、视频啊....)
  • 2.UDP一次发送的数据不能超过64KB
  • 3.UDP编程所需要的类:
   3.1 DatagramSocket:此类表示用来发送和接收数据报包的套接字,即用此类来实现数据的发送和传输
   3.2 DatagramPacket:此类表示数据报包,用此类将要发送的数据加以封装,再用DatagramSokcet传输


 DatagramSocket类的常用方法:
   public DatagramSocket(int port): 设置本机端口,ip地址默认为本机IP
   
   public void send(DatagramPacket dp): 将数据报包封装好的数据发送给目的主机

   public void reveive(DatagramPacket dp): 接受发送来的数据,在接收之前接收方会一直处于阻塞状态;
 

 DatagramPacket类的常用方法:

1.public DatagramPacket(byte[] buf,int length,InetAddress address,int port): 用来组装将要发送的数据,第一个参数为

要发送的数据的字节数组信息,第二个参数为字节数组的长度(注意是字节数组的长度,不是发送的数据的长度),第三个

参数是要发送的目的主机的IP地址,第四个参数是发送主机的端口号

 2.public DatagramPacket(byte[] buf,int length): 这个构造方法是用来接受发送方的数据,用一个字节数组来承放,另一个

参数意思是字节数组的长度,

3.public InetAddress getAddress(): 在获取到接受到的数据报包后,调用该方法获得发送方的IP地址;

4.public byte[] getData(): 返回将要发送的数据的字节数组,或者接受到的数据字节数组

5.public int getLength(): 返回将要发送的数据字节长度或者接收到的数据长度

 基于UDP协议的Socket编程

1.创建发送端

 a). 建立DatagramSocket对象,该端点建立,可以手动指定端口号。

 b).将数据进行packet包的封装,必须要指定目的地址和端口号信息;

 c). 通过socket服务的send方法将该包中发出

d).将socket关闭。

2.创建接受端

a).建立DatagramSocket对象,监听一个端口

b).通过socket的receive()方法将数据存入数据包中

c).通过数据包dp的方法getData()、getAddress()、getPort()等方法获得发送放的一些信息

d).将socket关闭


接下来看一个基于UDP的通信的例子:

发送方:

package udpsocket;
import java.net.*;

public class SendSocet {
	
	public static void main(String[] args) {
		
		DatagramSocket ds = null;
		DatagramPacket dp = null;
		
		try {
		
			ds = new DatagramSocket(8888);  //设置发送方的端口地址
			//System.out.println("等待用户连接。。。");
			String str = "我是你爸爸。。。";  //输入将要发送的信息
			dp = new DatagramPacket(str.getBytes(),str.getBytes().length,
					InetAddress.getByName("localhost"),6666); //将需要发送的信息加以组装
			ds.send(dp); //将组装好的信息发送给接收方
			System.out.println("发送成功。。。。");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}
 接受数据方:

package udpsocket;

import java.net.*;

public class ReceiveSocket {
	
	public static void main(String[] args) {
		
		DatagramSocket ds = null;
		DatagramPacket dp = null;
		
		try {
		
			ds = new DatagramSocket(6666);  //设置接收方的端口号
			System.out.println("等待数据发送。。。");
			//组装接收到的信息
			byte[] b = new byte[1024];
			dp = new DatagramPacket(b,b.length);
			System.out.print("接收到的信息为:");
			ds.receive(dp);  //用来接收发送方的发送来的数据,未接收到之前会一直阻塞
			byte[] data = dp.getData();
			System.out.println(new String(data,0,dp.getLength()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}
接收方在接收到数据之前会一直处于阻塞状态,具体如下:


 

在发送方发送数据成功后,接受方的结果为:


 

从上面这个简单的例子可以看出:UDP在进行通信时最大的好处就是面向无连接的通信,发送方可以随时发送信息,不必与接收方进行TCP协议中三次

握手的“麻烦”操作,同时一端既可以充当发送方,也可以充当接收方,因此,可以利用这一点实现两端通信,这还需要利用到多线程的知识,接下来就做

一个简单的实现。

发送方的发送线程:

package chat;

import java.io.*;
import java.net.*;

public class SendRunnable implements Runnable{
	
	private DatagramSocket ds; //ds由客户端决定
	private String destHost; //由客户端决定目的IP
	private int port; //由客户端决定目标端口
	
	public SendRunnable(DatagramSocket ds,String destHost,int port){
		this.ds = ds;
		this.destHost = destHost;
		this.port = port;
	}
	
	public void run(){
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //接收键盘输入
		DatagramPacket dp = null;
		try {
			//写一个死循环实现两端的不断通话
			while(true){
				
				System.out.print("我说:");
				String say = br.readLine(); //获取键盘输入的内容
				dp = new DatagramPacket(say.getBytes(),say.getBytes().length,
						InetAddress.getByName(destHost),port); //将键盘输入内容组成数据包发送给目标ip
				
				ds.send(dp); //发送数据包
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
}
 接收方的接受线程:

package chat;

import java.io.IOException;
import java.net.*;

public class ReceiveRunnable implements Runnable{
	
	private DatagramSocket ds; //用来接收发送方发送的数据
	
	public ReceiveRunnable(DatagramSocket ds){
		this.ds = ds;
	}
	
	//接收用户数据的线程
	public void run(){
		try {
			while(true){
			//	System.out.println();
				DatagramPacket dp = null;
				
				//定义承接发送方发送的数据的字节数组
				byte[] b = new byte[1024];
				dp = new DatagramPacket(b,b.length);
				ds.receive(dp); //接收发送的内容
				System.out.println();
				System.out.println(dp.getAddress().getHostName()+":"+dp.getPort()+"说:"
				+new String(dp.getData(),0,dp.getLength()));  //输出那个主机IP+端口号发送的消息
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	
}

写两个通信双方类:

package chat;

import java.net.DatagramSocket;
import java.net.SocketException;

public class ChatA {
	
	public static void main(String[] args) {
		
		try {
			DatagramSocket ds = new DatagramSocket(6666);
			new Thread(new SendRunnable(ds, "localhost",8888)).start();
			new Thread(new ReceiveRunnable(ds)).start();
		} catch (SocketException e) {
			e.printStackTrace();
		}
		
	}
	
}
package chat;

import java.net.DatagramSocket;
import java.net.SocketException;

public class ChatB {
	
	public static void main(String[] args) {
		
		try {
			DatagramSocket ds = new DatagramSocket(8888);
			new Thread(new SendRunnable(ds, "localhost",6666)).start();
			new Thread(new ReceiveRunnable(ds)).start();
		} catch (SocketException e) {
			e.printStackTrace();
		}
		
	}
	
	
}
看一下双方通信的结果吧:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值