Netty学习之二--Java socket编程(UDP实例)

来源:互联网 发布:纪晓波 吴佩慈 知乎 编辑:程序博客网 时间:2024/05/17 13:45

1.UDP和TCP的区别

(TCP)传输控制协议,是一种提供可靠数据传输的通用协议,由于TCP需要建立真实的连接,所以需要消耗服务器的负载要大于UDP
(UDP)用户数据报协议,是一个面向无连接的协议。采用该协议不需要两个应用程序先建立连接。UDP协议不提供差错恢复,不能提供数据重传,因此该协议传输数据安全性差。

2.UDP 编程

1.服务器代码

package com.ly.netty.scoket.N03.server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Server {
        private byte[] buf = new byte[1024];
        private DatagramPacket dp_receive = new DatagramPacket(bufbuf.length);
        public Server() {
            try {
                //客户端在8888端口监听接收到的数据  
                DatagramSocket socket = new DatagramSocket(8888);  
                System.out.println("Server started!");
                boolean f = true;
                while (f) {
                    socket.receive(dp_receive);
                    //接收到客户端的消息
                    String str_receive = new String(dp_receive.getData(),0,dp_receive.getLength()) +   
                            " from " + dp_receive.getAddress().getHostAddress() + ":" + dp_receive.getPort();  
                    System.out.println(str_receive);  
                    String str_send = "Hello I am server!" ;
                    DatagramPacket dp_send= new DatagramPacket(str_send.getBytes(),str_send.length(),dp_receive.getAddress(),9000);  
                    socket.send(dp_send);  
                }
                socket.close();
            } catch (SocketException e) {
                System.err.println("Can't open socket");
                System.exit(1);
            } catch (IOException e) {
                System.err.println("Communication error");
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            new Server();
        }
}

2.客户端代码
package com.ly.netty.scoket.N03.client;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client {
    private byte[] buf = new byte[1024];
    private static final int TIMEOUT = 1000; // 设置接收数据的超时时间
    private static final int MAXNUM = 10; // 设置重发数据的最多次数
    private void sendMessage(String msg) throws Exception {
        // 客户端在9000端口监听接收到的数据
        DatagramSocket ds = new DatagramSocket(8889);
        InetAddress loc = InetAddress.getLocalHost();
        // 定义用来发送数据的DatagramPacket实例
        DatagramPacket dp_send = new DatagramPacket(msg.getBytes(),
                msg.length(), loc, 8888);
        // 定义用来接收数据的DatagramPacket实例
        DatagramPacket dp_receive = new DatagramPacket(buf, 1024);
        // 数据发向本地9000端口
        ds.setSoTimeout(TIMEOUT); // 设置接收数据时阻塞的最长时间
        int tries = 0; // 重发数据的次数
        boolean response = false// 是否接收到数据的标志位
        // 直到接收到数据,或者重发次数达到预定值,则退出循环
        while (!response && tries < MAXNUM) {
            // 发送数据
            ds.send(dp_send);
            try {
                 ds.receive(dp_receive);  
                // 如果接收到的数据不是来自目标地址,则抛出异常
                if (!dp_receive.getAddress().equals(loc)) {
                    throw new IOException(
                            "Received packet from an umknown source");
                }
                // 如果接收到数据。则将receivedResponse标志位改为true,从而退出循环
                response = true;
            } catch (Exception e) {
                // 如果接收数据时阻塞超时,重发并减少一次重发的次数
                tries += 1;
                System.out.println("Time out," + (MAXNUM - tries)
                        + " more tries...");
            }
        }
        if (response) {
            String str_receive = new String(dp_receive.getData(), 0,
                    dp_receive.getLength())
                    + " from "
                    + dp_receive.getAddress().getHostAddress()
                    + ":"
                    + dp_receive.getPort();
            System.out.println(str_receive);
            System.out.println(str_receive);
            // 由于dp_receive在接收了数据之后,其内部消息长度值会变为实际接收的消息的字节数,
            // 所以这里要将dp_receive的内部消息长度重新置为1024
            dp_receive.setLength(1024);
        }else{
            //如果重发MAXNUM次数据后,仍未获得服务器发送回来的数据,则打印如下信息  
            System.out.println("No response!");  
        }
        
        ds.close();  
    }
    public static void main(String[] args) throws Exception {
        Client client = new Client();
        String msg = "Hello I am client!";
        client.sendMessage(msg);
    }
}

参考文献:http://blog.csdn.net/qq_23473123/article/details/51464272
http://blog.csdn.net/ns_code/article/details/14128987

1 0
原创粉丝点击