现在的位置: 首页 > 综合 > 正文

UDP Socket

2018年04月04日 ⁄ 综合 ⁄ 共 2805字 ⁄ 字号 评论关闭

UDP协议

 

UDP Socket在使用前不需要进行连接。TCP协议与电话通信相似,

而UDP协议则与邮件通信相似:你寄包裹或信件时不需要进行"连接",但是你得为每个包裹和信件指定目的地址

类似的,每条信息(即数据报文,datagram)负载了自己的地址信息,并与其他信息相互独立。

在接收信息时,UDP Socket扮演的角色就像是一个信箱,从不同地址发送来的信件和包裹都可以放到里面。

一旦被创建,UDP Socket就可以用来连续地向不同的地址发送信息,或从任何地址接收信息。

UDP协议所提供的端到端传输服务是尽力而为(best-effort)的,

即UDP Socket将尽可能地传送信息,但并不保证信息一定能成功到达目的地址,

而且信息到达的顺序与其发送顺序不一定一致(就像通过邮政部门寄信一样)。

因此,使用了UDP Socket的程序必须准备好处理信息的丢失和重排。 

为什么使用UDP?

UDP协议为程序带来了这个额外的负担,为什么还会使用它而不使用TCP协议呢?

原因之一是效率:如果应用程序只交换非常少量的数据,

例如从客户端到服务器端的简单请求消息,或一个反方向的响应消息,

TCP连接的建立阶段就至少要传输其两倍的信息量(还有两倍的往返延迟时间)。

另一个原因是灵活性:如果除可靠的字节流服务外,还有其他的需求,

UDP协议则提供了一个最小开销的平台来满足任何需求的实现。

Java程序员通过DatagramPacket 类和 DatagramSocket类来使用UDP套接字。

客户端和服务器端都使用DatagramSockets来发送数据,使用DatagramPackets来接收数据。

 

//UdpClient.java 

import java.io.IOException;
import java.net.DatagramPacket;
importjava.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;


public class UdpClient {

    private static final String SERVER_ADDRESS = "127.0.0.1";

    private static final int SERVER_PORT = 1111; 

    private static final String MSG = "test msg send to server";

    private static final int MAX_TRY = 5;

    private static final int SOCKET_TIME_OUT = 3000;

    public staticvoid main(String[] args) {
       try {

           InetAddress serverAddress = InetAddress.getByName(SERVER_ADDRESS); 

           DatagramPacket dp = new DatagramPacket(MSG.getBytes(), 0, MSG.length(), serverAddress, SERVER_PORT); 

           DatagramSocket datagramSocket = newDatagramSocket();

           int tries = 0;

           boolean isReceiveResponse = false;

           do {

              try {

                  datagramSocket.setSoTimeout(SOCKET_TIME_OUT);
                  datagramSocket.send(dp);

                  datagramSocket.receive(dp);                

                  if(!dp.getAddress().equals(serverAddress)){

                     thrownew IOException("Received packet from an unknown source");

                  }                

                  isReceiveResponse = true;

              } catch (SocketTimeoutException e) {

                  System.out.println("超时,尝试第" + (tries+1) + "连接");

                  tries ++ ;                 

              } catch (IOException e) {
                  e.printStackTrace();

              }
           } while (!isReceiveResponse && tries < MAX_TRY);       

          if(isReceiveResponse){
              String response = new String(dp.getData());
              System.out.println("receive:" + response);

           }else{
              System.out.println("No response -- giving up.");

           } 

           datagramSocket.close();

       } catch (UnknownHostException e) {
           e.printStackTrace();

       } catch (SocketException e) {

           e.printStackTrace();

       }
    }

}
//UdpServer.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; 

publicclass UdpServer {

    private static final int SERVER_PORT = 1111;

    private static final int MAX_BUF_SIZE = 255;  

    public static void main(String[] args) {

       try {

           DatagramSocket datagramSocket = new DatagramSocket(SERVER_PORT);          

           byte[] buf = newbyte[MAX_BUF_SIZE];          

           DatagramPacket dp = new DatagramPacket(buf,MAX_BUF_SIZE);         

           while(true){            
              try {

                  datagramSocket.receive(dp);                 

                  System.out.println("handle client at " + dp.getAddress().getHostAddress() + " on port" + dp.getPort());                 

                  datagramSocket.send(dp);                 

                  dp.setLength(MAX_BUF_SIZE);                 

              } catch (IOException e) {
                  e.printStackTrace();

              }            

           }               

       } catch (SocketException e) {

           e.printStackTrace();

       }    
    }

}

 

 

 

【上篇】
【下篇】

抱歉!评论已关闭.