* UPD传输不区分客户端跟服务端,* 这里用Send和Receive这两个方法决定谁发谁收
* 1.发送Send * 创建DatagramSocket,随机端口号* 创建DatagramPacket,指定数据、长度、地址、端口* 创建DatagramSocket发送DatagramPacket* 关闭DatagramSocket
代码如下:
package com.wsq.socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;public class Demo1_Send { //发送端 public static void main(String[] args) throws Exception {String str = "你,陪我度过蝉夏,越过城市喧嚣,歌声还在游走,你榴花般的双眸,不见你的温柔,丢失花间欢笑,岁月无法停留,流云的等候~~~"; //所要发送的数据DatagramSocket wsq = new DatagramSocket(); //创建Socket,相当于创建码头,端口号可以不指定,可以是随机端口号;比如,我有俩手机,用哪个手机给你发短信都是可以的DatagramPacket yy = new DatagramPacket(str.getBytes(), str.getBytes().length,InetAddress.getByName("192.168.1.178"),6666);//getByName里面填你要发送人的IP地址和要发送到的端口号//创建Packet,相当于是集装箱wsq.send(yy); //发货,将数据发出去,( 码头.send(集装箱) )wsq.close(); //底层是IO流,用完之后也得关掉,关闭码头}}
* 2,接收Receive* 创建DatagramSocket,指定端口号 也就是说,去哪个码头接货* 创建DategramPacket,指定数组,长度 接货的时候,得用箱子去装* 使用DategramSocket接收DatagramPacket Socket调用receive方法去接收Socket就行了* 关闭DatagramSocket* 从DatagramPacket中获取数据
代码如下:
package com.wsq.socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class Demo2_Receive { //接收端public static void main(String[] args) throws Exception {DatagramSocket wsq = new DatagramSocket(6666); //创建Socket,相当于创建码头,里面添加你想要接收的端口号,也就是去哪个码头接货DatagramPacket yy = new DatagramPacket(new byte[1024], 1024); //创建Packet,相当于创建集装箱,最好大小匹配 wsq.receive(yy); //接货,接收数据,数据全在Packet里面;(码头.集装箱)byte [] arr = yy.getData(); //获取数据,发过来的是一些字节数据,所以要用字节数组来接收//获取的不是把有效的获出来,而是把这里面存储的1024个字节给全部都获取出来;里面有些是空的没存东西的,得把有效的字节个数给获取出来int len = yy.getLength(); //获取有效的字节个数//知道有效的字节个数了,也知道数据了,然后转换为对应的字符串System.out.println(new String (arr,0,len)); //arr,0,len;将arr这个数组,从0开始到len结束wsq.close();}}
代码的运行,这里为了看出效果,在DOS模拟器下运行两个程序;先运行接收端,再运行发送端
接收端:
发送端:
发送端将
“你,陪我度过蝉夏,越过城市喧嚣,歌声还在游走,你榴花般的双眸,不见你的温柔,丢失花间欢笑,岁月无法停留,流云的等候~~~”这个数据,
给发送到接收端,接收端已接收
从这上面的例子可以看出,只能传递指定的数据,上面的例子只是传输了一句话而已,那要是想要传输键盘录入的数据又该怎样传输呢?于是,小编做了些代码的优化:
package www.wsq.Socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;public class Demo1_Send { //发送端public static void main(String[] args) throws Exception {Scanner sc = new Scanner(System.in); //创建键盘录入对象scDatagramSocket wsq = new DatagramSocket(); //创建Socket,相当于创建码头,端口号可以不指定,可以是随机端口号;比如,我有俩手机,用哪个手机给你发短信都是可以的while(true){ //想把数据不断的发送,这里就定义了一个while循环String line = sc.nextLine(); //不断地去获取键盘录入的数据,获取键盘录入的字符串if("quit".equals(line)){ //对字符串做一个判断,如果不判断的话,while这个循环永远也结束不了,录入quit,跳出循环break;}DatagramPacket yy = new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.1.178"),6666);//getByName里面填你要发送人的IP地址和要发送的数据//创建Packet,相当于是集装箱wsq.send(yy); //发货,将数据发出去,( 码头.send(集装箱) )} wsq.close(); //底层是IO流,用完之后也得关掉,关闭码头}}
package www.wsq.Socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class Demo2_Receive { //接收端public static void main(String[] args) throws Exception {DatagramSocket wsq = new DatagramSocket(6666); //创建Socket,相当于创建码头,里面添加你想要接收的端口号,也就是去哪个码头接货DatagramPacket yy = new DatagramPacket(new byte[1024], 1024); //创建Packet,相当于创建集装箱,最好大小匹配 while(true){ //while循环,不断地去接收数据wsq.receive(yy); //接货,接收数据,数据全在Packet里面;(码头.集装箱)byte [] arr = yy.getData(); //获取数据,发过来的是一些字节数据,所以要用字节数组来接收//获取的不是把有效的获出来,而是把这里面存储的1024个字节给全部都获取出来;里面有些是空的没存东西的,得把有效的字节个数给获取出来int len = yy.getLength(); //获取有效的字节个数/*加个IP地址和端口号,为了看的更加明显点*/String ip = yy.getAddress().getHostAddress(); //获取IP地址int port = yy.getPort(); //获取端口号//知道有效的字节个数了,也知道数据了,然后转换为对应的字符串System.out.println(ip + ":" + port + ":" + new String (arr,0,len)); //arr,0,len;将arr这个数组,从0开始到len结束//输出IP地址加端口号加要发送的内容//由于要不断地接收数据,这里的流就不管了//wsq.close();}}}
这样就可以实现多数据的发送与接收了
左边是接收端,右边是发送端
从这上面两个例子可以看出,程序运行得启动两个DOS模拟器窗口,很麻烦,那,要是想要再一个窗口下执行,又该怎么办呢?这里就要用到多线程,开启两条线程,同时在主线程里面跑,这就可以同时运行,接收的同时再去发送,于是,小编在代码的优化的基础上又做了些优化:
package com.wsq.socket;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;public class Demo3_MoreThread {public static void main(String[] args) {new Receive().start(); //开启线程 new Send().start(); //开启线程}}class Send extends Thread{public void run(){try {Scanner sc = new Scanner(System.in); //创建键盘录入对象scDatagramSocket wsq = new DatagramSocket(); //创建Socket,相当于创建码头,端口号可以不指定,可以是随机端口号;比如,我有俩手机,用哪个手机给你发短信都是可以的while(true){ //想把数据不断的发送,这里就定义了一个while循环String line = sc.nextLine(); //不断地去获取键盘录入的数据,获取键盘录入的字符串if("quit".equals(line)){ //对字符串做一个判断,如果不判断的话,while这个循环永远也结束不了,录入quit,跳出循环break;}DatagramPacket yy = new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.1.178"),6666);//getByName里面填你要发送人的IP地址和要发送的数据//创建Packet,相当于是集装箱wsq.send(yy); //发货,将数据发出去,( 码头.send(集装箱) )} wsq.close(); //底层是IO流,用完之后也得关掉,关闭码头} catch (IOException e) {e.printStackTrace();}}
}class Receive extends Thread{public void run(){try {DatagramSocket wsq = new DatagramSocket(6666); //创建Socket,相当于创建码头,里面添加你想要接收的端口号,也就是去哪个码头接货DatagramPacket yy = new DatagramPacket(new byte[1024], 1024); //创建Packet,相当于创建集装箱,最好大小匹配 //只能try,catch捕获异常,因为在run方法里面不能抛异常while(true){ //while循环,不断地去接收数据wsq.receive(yy); //接货,接收数据,数据全在Packet里面;(码头.集装箱)byte [] arr = yy.getData(); //获取数据,发过来的是一些字节数据,所以要用字节数组来接收//获取的不是把有效的获出来,而是把这里面存储的1024个字节给全部都获取出来;里面有些是空的没存东西的,得把有效的字节个数给获取出来int len = yy.getLength(); //获取有效的字节个数/*加个IP地址和端口号,为了看的更加明显点*/String ip = yy.getAddress().getHostAddress(); //获取IP地址int port = yy.getPort(); //获取端口号//知道有效的字节个数了,也知道数据了,然后转换为对应的字符串System.out.println(ip + ":" + port + ":" + new String (arr,0,len)); //arr,0,len;将arr这个数组,从0开始到len结束//输出IP地址加端口号加要发送的内容//由于要不断地接收数据,这里的流就不管了//wsq.close();} } catch (IOException e) {e.printStackTrace();}}
}