1. 程式人生 > >Socket和DatagramSocket的區別

Socket和DatagramSocket的區別

簡而言之就是:

Socket使用的tcp連線,需要先連線之後才能傳送資料。

DatagramSocket使用的UDP連線,客戶端不需要先連線資料,可以直接傳送給指定服務端。

DatagramSocket:

客戶端傳送(直接傳送資料,沒有連線的過程):

protected void connectServerWithUDPSocket(Context context, String id) {
        DatagramSocket socket;
        try {
            //建立DatagramSocket物件並指定一個埠號,注意,如果客戶端需要接收伺服器的返回資料,
            //還需要使用這個埠號來receive,所以一定要記住
            socket = new DatagramSocket(null);
            //使用InetAddress(Inet4Address).getByName把IP地址轉換為網路地址
            InetAddress serverAddress = null;
            mHost = Utils.getLocalIpStr(context);
            Log.d(TAG, "connectServerWithUDPSocket mHost =" + mHost);
            if (null == mHost) return;
            try {
                serverAddress = InetAddress.getByName(mHost);
            } catch (UnknownHostException e) {
                Log.d(TAG, "未找到伺服器");
                e.printStackTrace();
            }
            //Inet4Address serverAddress = (Inet4Address) Inet4Address.getByName("192.168.1.32");
            String str = id;//設定要傳送的報文
            byte data[] = str.getBytes();//把字串str字串轉換為位元組陣列
            //建立一個DatagramPacket物件,用於傳送資料。
            //引數一:要傳送的資料  引數二:資料的長度  引數三:服務端的網路地址  引數四:伺服器端埠號
            DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, PORT);
            try {
                socket.send(packet);//把資料傳送到服務端。
            } catch (IOException e) {
                Log.d(TAG, "傳送失敗");
                e.printStackTrace();
            }
            Log.d(TAG, "socket.send------------------------");
        } catch (SocketException e) {
            Log.i(TAG, "建立接收資料報失敗");
            e.printStackTrace();
        }
    }

服務端接收:

public void serverReceviedByUdp() {
        //建立一個DatagramSocket物件,並指定監聽埠。(UDP使用DatagramSocket)
        DatagramSocket socket;
        try {
            socket = new DatagramSocket(PORT);
            //建立一個byte型別的陣列,用於存放接收到得資料
            byte data[] = new byte[4 * 1024];
            //建立一個DatagramPacket物件,並指定DatagramPacket物件的大小
            DatagramPacket packet = new DatagramPacket(data, data.length);
            while (true) {
                //讀取接收到得資料
                socket.receive(packet);
                //把客戶端傳送的資料轉換為字串。
                //使用三個引數的String方法。引數一:資料包 引數二:起始位置 引數三:資料包長
                String result = new String(packet.getData(), packet.getOffset(), packet.getLength());
                Log.d(TAG, "service result = " + result);
                
            }

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

Socket:

服務端:

public class TcpServer {
    private static ServerSocket serverSocket;
    private static Socket socket;

    public static void startServer(){
        if (serverSocket == null){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        serverSocket = new ServerSocket(8080);
                        Log.i("tcp" , "伺服器等待連線中");
                        socket = serverSocket.accept();
                        Log.i("tcp" , "客戶端連線上來了");
                        InputStream inputStream = socket.getInputStream();
                        byte[] buffer = new byte[1024];
                        int len = -1;
                        while ((len = inputStream.read(buffer)) != -1) {
                            String data = new String(buffer, 0, len);
                            Log.i("tcp" , "收到客戶端的資料-----------------------------:" + data);
                            EventBus.getDefault().post(new MessageServer(data));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();

                    }finally {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        try {
                            serverSocket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        socket = null;
                        serverSocket = null;
                    }
                }
            }).start();
        }
    }

    public static void sendTcpMessage(final String msg){
        if (socket != null && socket.isConnected()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        socket.getOutputStream().write(msg.getBytes());
                        socket.getOutputStream().flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

客戶端(這邊需要先連線服務端之後,才能傳送資料):

public class TcpClient {

    public static Socket socket;

    public static void startClient(final String address ,final int port){
        if (address == null){
            return;
        }
        if (socket == null) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Log.i("tcp", "啟動客戶端");
                        socket = new Socket(address, port);
                        Log.i("tcp", "客戶端連線成功");
                        PrintWriter pw = new PrintWriter(socket.getOutputStream());

                        InputStream inputStream = socket.getInputStream();

                        byte[] buffer = new byte[1024];
                        int len = -1;
                        while ((len = inputStream.read(buffer)) != -1) {
                            String data = new String(buffer, 0, len);
                            Log.i("tcp", "收到伺服器的資料---------------------------------------------:" + data);
                            EventBus.getDefault().post(new MessageClient(data));
                        }
                        Log.i("tcp", "客戶端斷開連線");
                        pw.close();

                    } catch (Exception EE) {
                        EE.printStackTrace();
                        Log.i("tcp", "客戶端無法連線伺服器");

                    }finally {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        socket = null;
                    }
                }
            }).start();
        }
    }

    public static void sendTcpMessage(final String msg){
        if (socket != null && socket.isConnected()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        socket.getOutputStream().write(msg.getBytes());
                        socket.getOutputStream().flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

參考: