网络编程之udp
计算机网络,就是把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。
网络体系结构:国际标准化组织ISO于l978年提出“开放系统互连参考模型”,即著名的OSI(Open System Interconnection)模型。该模型把计算机网络分成物理层、数据链路层、网络层、传输层、会话层、表示层、应用层等七层。
通信协议
计算机网络中实现通信必须有一些约定,即通信协议。对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。
TCP协议:提供可靠的数据传输服务的规则。
IP协议进行IP数据包的分割和组装。
但是通过IP协议并不能清楚地了解到数据包是否顺利地发送给目标计算机。而使用TCP协议,它将数据包成功发送给目标计算机后,会要求发送一个确认,如果在某个时间内没有收到确认,TCP将重新发送数据包。
首先了解一下神马是UDP协议;
UDP( User Datagram Protocol )协议是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。
UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
为什么要使用UDP?
在网络质量令人不十分满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如聊天用的ICQ和OICQ就是使用的UDP协议。
上网搜索摸个网站的时候,本机是先访问本地的hosts文件区,去找该主机名是否有对应的ip地址;
C:\Windows\System32\drivers\etc\hosts;在里面可以加上你经常进的网站和ip;
InetAddress:用于描述IP地址的对象
InetAddress类没有提供构造方法,而是提供了两个静态方法来获取InetAddress实例
getByName(String host):根据主机获取对应的InetAddress对象。
getByAddress(byte[] addr):根据原始IP地址来获取对应的InetAddress对象。
//将指定ip封装成InetAddress对象。
InetAddress ia = InetAddress.getByName("127.0.0.1");
在Java中操纵UDP
使用位于JDK中Java.net包下的DatagramSocket和DatagramPacket类,可以非常方便地控制用户数据报文。
每个数据包的大小限制在64k内;
面向无连接,是不可靠协议,容易丢包;
不需要连接,速度快;
DatagramSocket类:创建接收和发送UDP的Socket实例
DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。
DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。
receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。
send(DatagramPacket d):发送报文d到目的地。
setSoTimeout(int timeout):设置超时时间,单位为毫秒。
close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。
建立一个upd的发送端。
用于发送数据。
1,建立updsocket服务。
2,将数据封装成数据包。
3,通过socket服务的send方法。将数据包发出。
4,关闭资源。
*/
//1,建立udpsocket服务。
DatagramSocket ds=new DatagramSocket;
//2,将数据封装成数据包。要使用DatagramPacket对象
//2.1先将要发送的数据变成字节数组。在指定发送的目的地和端口。
//2.2将这些信息作为参数传递给数据包对象的构造函数。
byte[] bf=”hahah ,wolaile ”.getBytes[];
InetAdress ip=InetAdress.getName(“192.168.49.111”);
DatagramPacket dp=new DatagramPacket(bf,bf.getLength,ip,9909);
//3,使用Socket服务的send方法将数据包发送出去。
Ds.send(dp);
//4,关闭资源。
ds.close;
/*
建立udp的接收端。
1,建立udp接收端服务,必须要监听一个端口,因为要明确,哪个端口来的数据是由该应用程序所处理的。
2,建立一个空的数据包,用于存储接收到数据,
将字节数据存储到数据包对象中,可以使用数据包对象的方法获取不同的数据信息。
3,使用Socket服务的receive方法将接收到的数据存储到数据包中。
4,通过数据包的方法获取指定数据信息。
5,关闭资源。
*/
//1,建立updsocket服务,监听一个端口。
DatagramSocket ds=new DatagramSocket(9909);
//2,建立一个执行大小的数据包,用于存储数据,以便获取。
byte[] bf=new byte[1024];
DatagramPacket dp=new DatagramPacket(bf,bf.getLength);
//3,使用socket的receive方法将数据存储到数据包中。
ds.receive();
//4,通过数据包对象的方法获取其中的数据。
String ip=getAddress().getHostAdress();
String data=new String(dp.getData(),0,dp.getLength);
int port =dp.getPort();
System.out.println(ip+”:”+data+”::”+port);
//5,关闭资源。
ds.close();
package com.csdn.hbsi;
/*
需求:
制作一个dos版的聊天程序。
1,对于聊天分两个动作,接收和发送。
2,接收和发送都需要同时运行。这就使用到了多线程技术。
一个线程控制接收,一个线程控制发送。
3,既然要进行群聊。那么就要使用socket网络服务。这里我们使用Udp完成。
*/
import java.net.*;
import java.io.*;
class ChatSend implements Runnable
{
private DatagramSocket ds;
ChatSend(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
BufferedReader bufr = null;
try
{
bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null)
{
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.49.255"),9008);
ds.send(dp);
}
ds.close();
}catch (Exception e)
{
System.out.println(e.toString());
}
}
}
class ChatRece implements Runnable
{
private DatagramSocket ds;
ChatRece(DatagramSocket ds){
this.ds = ds;}
public void run(){
while(true){
try{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+"::"+data);
}catch (Exception e){
System.out.println(e.toString());
}
}
}
}
class ChatDemo
{
public static void main(String[] args) throws Exception{
DatagramSocket send = new DatagramSocket();
DatagramSocket rece = new DatagramSocket(9008);
new Thread(new ChatSend(send)).start();
new Thread(new ChatRece(rece)).start();
}
}