socket 套接字
我们好比将UDP通信比作成为我们上网购物时候的物流。在卖家那里打包快递之后通过物流运送到我们的手上,我们在将他拆开。 这样子是比较贴切的比喻我们网络中传输数据的一个过程。socket 的意思,顾名思义就是插口的意思。两个双方通信方都需要插口,这样子才能够实施通信。
UDP通信
用户数据报(UDP)是网络信息传输的另一种形式。基于UDP的通信和基于TCP的通信不同,基于UDP的信息传递更快,但是不提供可靠的保障。使用UDP传输数据时,用户无法知道数据能否正确地到达主机,也不能确定到达的目的地的顺序是否和发送的顺序是相同的。虽然UDP是一种不可靠的协议,但是如果需要比较快的去传输信息,并能容忍小的错误,可以考虑使用UDP。
UDP通信的基本模式:
1.将数据打包,然后将数据包发往目的地。
2.接别人发来的数据包,然后进行查看数据包。
发送数据包:
1.使用DatagramSocket()创建一个数据包套接字
2.使用DatagramPacket(byte[]buf,int offset,int length,InetAddress address,int port)创建要发送的数据包
3.使用DatagramSocket类的send()方法发送数据包
接受数据包:
4.使用DatagramSocket(int port )创建数据包套接字,绑定到指定的端口
5.使用DatagramPacket(byte[]buf,int length)创建字节数组来接受数据包
6.使用DatagramPacket类的receive()方法接受UDP包
DatagramPacket类
DatagramPacket(byte[]buf,int length)
DatagramPacket(byte[]buf,int offset,int length,InetAddress address,int port)
DatagramSocket类
DatagramSocket()
DatagramSocket(int port)
DatagramSocket(int port,InetAddress addr)
UDP发送端(send)
1.建立UDPSocket服务
2.提供数据,将数据封装到数据包中
3.通过Socket服务将已有的数据包发送出去,通过Send方法
4.关闭
UDP接收端(Receive)
1.定义UDPsocket(通常会有一个监听一个端口,其实就是给这个接受网络应用程序)
2.定义一个数据包,因为要储存接收到的字节数据,因为数据包对象中有更多的功能可以提取字节数据存入已定义好的数据包中
3.通过Socket服务的receive方法将受到的数据存入已定义好的数据中。
4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上。
5.关闭资源(但是这里的服务器是可以不用关闭的)
一个程序为服务端,建立UDP服务端套接字。另外一个程序为客户端,建立UDP客户端套接字。这两个新程序可以互联,完成一个基于TCP/IP网络的文本聊天程序。
代码开始之前,我们需要先查看自己的IPV4的地址,可以用JAVA代码,也可以用DOS命令行中的IPconfig
import java.net.*;
public class IPdemo {
public static void main(String args[])throws Exception{
InetAddress i=InetAddress.getLocalHost();
System.out.print(i.toString());
}
}
结果
afterjourney/10.32.0.114
这是我的主机号和IP地址
好,然后开始切入正题
/*
UDP发送器
*/
import java.io.*;
import java.net.*;
class udpsend1{
public static void main(String args[])throws Exception{//这里需要抛出报错
DatagramSocket ds=new DatagramSocket();//创建一个UDPsocket服务
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//键盘上进行输入的时候需要用到的IO流
String line=null;
while((line=bufr.readLine())!=null){//判断是否line为空,这里注意readLine是阻塞式,意思是如果没有输出就一直等待,知道输出。
if("886".equals(line))//当输入时886时,结束聊天
break;
byte[] buf=line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("10.32.0.114"),8888);//
ds.send(dp);//将dp里的东西方发送给ds
}
ds.close();//关闭
}
}
/*
UDP服务器
*/
class udprece1{
public static void main(String args[])throws Exception {//这里需要抛出
DatagramSocket ds=new DatagramSocket(8888);//端口号是任意的,但是我们需要主要到要和发送器的端口号保持一致
while(true){//死循环
byte[] buf=new byte[1024];//1024足够
DatagramPacket dp=new DatagramPacket(buf,buf.length);//创建字节数组来接受数据包
ds.receive(dp);//接收数据然后放在ds中
String ip=dp.getAddress().getHostAddress();//获取主机地址
String data=new String(dp.getData(),0,dp.getLength());//截取0到字符串长度的内容放在data中 用于输出显示在服务器上
System.out.println(ip+"::"+data);
}
}
}
结果
我的Myeclipse中无法在console中进行操作,所以我在DOS命令行中进行了操作。
但是我又发现了一个有关于现在主流JAVA编辑器的一个好处,我之前的电脑是重新安装过一遍,可能由于系统更新将我之前更改的环境变量抹去。但是我直接安装了myeclipse,我也可以在没有配置变量的情况之下进行操作和java文件。所以我认为,其实myeclipse它是有自动寻找和自动去配置环境变量的能力,当我今天编写代码时候才用到DOS 发现javac 不是外部或者内部指令的时候我意识到了这一点。
打开两个DOS命令行,编译 源文件,一定要打开服务器(先JAVA udprece1)后先打开发送器(JAVA udpsend1)才可以,否则UDP通信无法建立,我就是在这里一直思考了两个小时,才发现中这其中的原理。