1. 程式人生 > >TCP UDP Socket 即時通訊 API 示例

TCP UDP Socket 即時通訊 API 示例

Markdown版本筆記 我的GitHub首頁 我的部落格 我的微信 我的郵箱

TCP Socket 即時通訊 API 示例

目錄

TCP 案例

SocketActivity

public class SocketActivity extends ListActivity implements Client.MsgListener {
    public static final int PORT = 11232;
    public static final String HOST = "192.168.1.187"; //此 IP 為內網 IP ,所有隻有在同一區域網下才能通訊(連線同一WIFI即可)

    private TextView msgTextView;
    private EditText editText;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] array = {"開啟伺服器",
            "開啟客戶端",
            "客戶端發訊息",
            "客戶端下線"};
        setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(array)));

        editText = new EditText(this);
        getListView().addFooterView(editText);

        msgTextView = new TextView(this);
        getListView().addFooterView(msgTextView);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        switch (position) {
            case 0:
                Server.SINGLETON.startServer(PORT);
                break;
            case 1:
                Client.SINGLETON.startClient(HOST, PORT);
                Client.SINGLETON.setListener(this);
                break;
            case 2:
                Client.SINGLETON.sendMsg(editText.getText().toString());
                break;
            case 3:
                Client.SINGLETON.exit();
                break;
            default:
                break;
        }
    }

    private SpannableString getSpannableString(String string, int color) {
        SpannableString mSpannableString = new SpannableString(string);
        ForegroundColorSpan colorSpan = new ForegroundColorSpan(color);
        mSpannableString.setSpan(colorSpan, 0, mSpannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return mSpannableString;
    }

    @Override
    public void onReveiveMsg(String message) {
        runOnUiThread(() -> msgTextView.append(getSpannableString(message + "\n", Color.BLUE)));
    }

    @Override
    public void onSendMsg(String message) {
        runOnUiThread(() -> {
            String text = Client.SINGLETON.getName() + " : " + editText.getText().toString() + "\n";
            msgTextView.append(getSpannableString(text, Color.RED));
        });
    }
}

服務端 Server

public enum Server {
    SINGLETON;

    public static final int MAX_TEXT_SIZE = 1024;
    public static final String CLIENT_EXIT_CMD = "拜拜";
    public static final String CHARSET = "GBK";

    private Set<Socket> socketSet;
    private boolean serverExit = false;
    private ServerSocket server;//伺服器物件

    Server() {
        socketSet = new HashSet<>();//使用者集合
    }

    public void startServer(int port) {
        if (server != null && !server.isClosed()) {
            System.out.println("伺服器已開啟,不需要重複開啟");
        } else {
            new Thread(() -> {
                try {
                    server = new ServerSocket(port);
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("伺服器啟動失敗");
                    return;
                }

                System.out.println("伺服器啟動成功");
                //迴圈監聽
                while (!serverExit) {
                    try {
                        Socket socket = server.accept();//獲取連線過來的客戶端物件。阻塞方法
                        socketSet.add(socket);
                        sendUserMsg(socket, getName(socket) + " 上線了, 當前 " + socketSet.size() + " 人線上");
                        listenerUserMsg(socket); //監聽客戶端傳送的訊息,並轉發給其他使用者
                    } catch (IOException e) {//使用者下線
                        e.printStackTrace();
                    }
                }
                System.out.println("伺服器已關閉");
            }).start();
        }
    }

    private void listenerUserMsg(Socket socket) {
        new Thread(() -> {
            try {
                byte[] bytes = new byte[MAX_TEXT_SIZE];
                int count;
                boolean clinetExit = false;
                while (!serverExit && !clinetExit && !socket.isClosed() && (count = socket.getInputStream().read(bytes)) != -1) {
                    String text = new String(bytes, 0, count, CHARSET);
                    System.out.println("伺服器已收到【" + getName(socket) + "】傳送的資訊【" + text + "】");
                    clinetExit = CLIENT_EXIT_CMD.equals(text);
                    sendUserMsg(socket, getName(socket) + " : " + text);
                }
            } catch (IOException e) {//關閉與此使用者相關的流
                e.printStackTrace();
                System.out.println(getName(socket) + " 異常掉線");
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    socketSet.remove(socket);
                    sendUserMsg(socket, getName(socket) + " 下線了, 當前 " + socketSet.size() + " 人線上");
                }
            }
        }).start();
    }

    private void sendUserMsg(Socket socket, String text) {
        for (Socket otherSocket : socketSet) {//遍歷所有的線上使用者
            if (otherSocket != null && !otherSocket.isClosed() && !otherSocket.equals(socket)) {
                try {
                    OutputStream outputStream = otherSocket.getOutputStream();//獲取相應的輸出流,把資訊傳送過去
                    outputStream.write(text.getBytes(CHARSET));
                    outputStream.flush();
                    System.out.println("伺服器已轉發資訊【" + text + "】給【" + getName(otherSocket) + "】");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println(getName(socket) + " 異常");
                }
            }
        }
    }

    private String getName(Socket socket) {
        return "使用者" + socket.getInetAddress().getHostAddress() + "_" + socket.getPort();
    }
}

客戶端 Client

public enum Client {

    SINGLETON;

    Client() {
    }

    public static final int MAX_TEXT_SIZE = 1024;
    public static final String CLIENT_EXIT_CMD = "拜拜";
    public static final String CHARSET = "GBK";

    private boolean exit = false;
    private Socket socket;

    private MsgListener listener;

    public void startClient(String host, int port) {
        if (socket != null && !socket.isClosed()) {
            System.out.println("客戶端已開啟,不需要重複開啟");
        } else {
            new Thread(() -> {
                try {
                    socket = new Socket(host, port);//建立客戶端物件
                    listenerUserMsg(); //監聽訊息
                    System.out.println("客戶端已開啟成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("客戶端已開啟失敗");
                }
            }).start();
        }
    }

    private void listenerUserMsg() {
        new Thread(() -> {
            try {
                byte[] bytes = new byte[MAX_TEXT_SIZE];
                int count;
                while (!exit && socket != null && !socket.isClosed() && (count = socket.getInputStream().read(bytes)) != -1) {
                    String text = new String(bytes, 0, count, CHARSET);
                    System.out.println(getName() + " 收到資訊【" + text + "】");
                    if (listener != null) {
                        listener.onReveiveMsg(text);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    public void sendMsg(String text) {
        new Thread(() -> {
            if (socket != null && !socket.isClosed()) {
                try {
                    socket.getOutputStream().write(text.getBytes(CHARSET));//獲取socket流中的輸出流將指定的資料寫出去
                    if (listener != null) {
                        listener.onSendMsg(text);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void exit() {
        new Thread(() -> {
            exit = true;
            if (socket != null && !socket.isClosed()) {
                try {
                    socket.getOutputStream().write(CLIENT_EXIT_CMD.getBytes(CHARSET));
                    socket.close();
                    System.out.println("客戶端下線成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("客戶端下線異常");
                }
            } else {
                System.out.println("客戶端已下線,不需要重複下線");
            }
        }).start();
    }

    public String getName() {
        return "使用者" + socket.getInetAddress().getHostAddress() + "_" + socket.getPort();
    }

    public void setListener(MsgListener listener) {
        this.listener = listener;
    }

    public interface MsgListener {
        void onReveiveMsg(String message);

        void onSendMsg(String message);
    }
}

UDP 案例

SocketActivity

public class SocketActivity extends ListActivity implements Client.MsgListener {
    private boolean tag = true;
    public static final int PORT1 = 11233;
    public static final int PORT2 = 11234;
    public static final String HOST1 = "192.168.2.124";
    public static final String HOST2 = "192.168.2.177";

    private TextView msgTextView;
    private EditText editText;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] array = {"切換配置",
            "開啟客戶端",
            "客戶端發訊息",
            "客戶端下線"};
        setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(array)));

        editText = new EditText(this);
        getListView().addFooterView(editText);

        msgTextView = new TextView(this);
        getListView().addFooterView(msgTextView);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        switch (position) {
            case 0:
                tag = !tag;
                break;
            case 1:
                Client.SINGLETON.startClient(tag ? PORT1 : PORT2);
                Client.SINGLETON.setListener(this);
                break;
            case 2:
                try {
                    //getLocalHost(),getByName("127.0.0.1"),getByName("192.168.0.255"),getByAddress(new byte[]{127,0,0,1})
                    InetAddress address = InetAddress.getByName(tag ? HOST2 : HOST1);
                    Client.SINGLETON.sendMsg(editText.getText().toString(), address, tag ? PORT2 : PORT1);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                break;
            case 3:
                Client.SINGLETON.exit();
                break;
            default:
                break;
        }
    }

    private SpannableString getSpannableString(String string, int color) {
        SpannableString mSpannableString = new SpannableString(string);
        ForegroundColorSpan colorSpan = new ForegroundColorSpan(color);
        mSpannableString.setSpan(colorSpan, 0, mSpannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return mSpannableString;
    }

    @Override
    public void onReveiveMsg(String message) {
        runOnUiThread(() -> msgTextView.append(getSpannableString(message + "\n", Color.BLUE)));
    }

    @Override
    public void onSendMsg(String message) {
        runOnUiThread(() -> {
            String text = Client.SINGLETON.getName() + " : " + editText.getText().toString() + "\n";
            msgTextView.append(getSpannableString(text, Color.RED));
        });
    }
}

Client

public enum Client {

    SINGLETON;

    Client() {
    }

    public static final int MAX_TEXT_SIZE = 1024;
    public static final String CHARSET = "GBK";

    private boolean exit = false;
    private DatagramSocket send;
    private DatagramSocket receiver;
    private MsgListener listener;

    public void startClient(int port) {
        if (send != null && !send.isClosed()) {
            System.out.println("客戶端" + port + "已開啟,不需要重複開啟");
        } else {
            new Thread(() -> {
                try {
                    send = new DatagramSocket();
                    receiver = new DatagramSocket(port);
                    listenerUserMsg(); //監聽訊息
                    System.out.println("客戶端" + port + "已開啟成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("客戶端" + port + "已開啟失敗");
                }
            }).start();
        }
    }

    private void listenerUserMsg() {
        new Thread(() -> {
            try {
                byte[] bytes = new byte[MAX_TEXT_SIZE];
                DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
                while (!exit && receiver != null && !receiver.isClosed()) {
                    receiver.receive(packet);//持續接收資料
                    String text = new String(packet.getData(), 0, packet.getLength(), CHARSET);
                    System.out.println(getName() + " 收到資訊【" + text + "】");
                    if (listener != null) {
                        listener.onReveiveMsg(text);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    public void sendMsg(String text, InetAddress address, int port) {
        new Thread(() -> {
            if (send != null && !send.isClosed()) {
                try {
                    String content = getName() + " : " + text;
                    byte[] buf = content.getBytes(CHARSET);
                    DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
                    send.send(packet);
                    if (listener != null) {
                        listener.onSendMsg(text);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void exit() {
        new Thread(() -> {
            exit = true;
            if (send != null && !send.isClosed()) {
                send.close();
            }
            if (receiver != null && !receiver.isClosed()) {
                receiver.close();
            }
            System.out.println("客戶端下線成功");
        }).start();
    }

    public String getName() {
        return "使用者" + receiver.getLocalPort();
    }

    public void setListener(MsgListener listener) {
        this.listener = listener;
    }

    public interface MsgListener {
        void onReveiveMsg(String message);

        void onSendMsg(String message);
    }
}

常見異常

  • BindException:Address already in use: JVM_Bind 該異常發生在伺服器端進行new ServerSocket(port)操作時。異常的原因是此port埠已經被佔用。此時用netstat –an命令,可以看到一個Listending狀態的埠。只需要找一個沒有被佔用的埠就能解決這個問題。
  • ConnectException: Connection refused: connect 該異常發生在客戶端進行new Socket(ip, port)操作時,該異常發生的原因是或者具有此ip地址的機器不能找到,或者是該ip存在但找不到指定的埠進行監聽。出現該問題,首先檢查客戶端的ip和port是否寫錯了,如果正確則從客戶端ping一下伺服器看是否能ping通,如果能ping通再看在伺服器端的監聽指定埠的程式是否啟動。
  • Socket is closed 該異常在客戶端和伺服器均可能發生。異常的原因是連線已被關閉後(呼叫了Socket的close方法)再對網路連線進行讀寫操作。
  • SocketException:(Connection reset 或者 Connect reset by peer:Socket write error) 該異常在客戶端和伺服器端均有可能發生,引起該異常的原因有兩個,第一個就是如果一端的Socket被關閉,另一端仍傳送資料,傳送的第一個資料包引發該異常(Connect reset by peer)。另一個是一端退出,但退出時並未關閉該連線,另一端如果在從連線中讀資料則丟擲該異常(Connection reset)。簡單的說就是在連線斷開後的讀和寫操作引起的。
  • SocketException: Broken pipe 該異常在客戶端和伺服器均有可能發生。在上面那種異常的第一種情況中(也就是丟擲SocketExcepton:Connect reset by peer:Socket write error),如果再繼續寫資料則丟擲該異常。前兩個異常的解決方法是首先確保程式退出前關閉所有的網路連線,其次是要檢測對方的關閉連線操作,發現對方關閉連線後自己也要關閉該連線。

API

ServerSocket

構造方法

  • ServerSocket() 建立非繫結伺服器套接字。
  • ServerSocket(int port) 建立繫結到特定埠的伺服器套接字。
  • ServerSocket(int port, int backlog) 利用指定的 backlog 建立伺服器套接字並將其繫結到指定的本地埠號。
  • ServerSocket(int port, int backlog, InetAddress bindAddr) 使用指定的埠、偵聽 backlog 和要繫結到的本地 IP 地址建立伺服器。

常用方法

  • Socket accept() 偵聽並接受到此套接字的連線。
  • void bind(SocketAddress endpoint) 將 ServerSocket 繫結到特定地址(IP 地址和埠號)。
  • void bind(SocketAddress endpoint, int backlog) 將 ServerSocket 繫結到特定地址(IP 地址和埠號)。
  • void close() 關閉此套接字。
  • ServerSocketChannel getChannel() 返回與此套接字關聯的唯一 ServerSocketChannel 物件(如果有)。
  • InetAddress getInetAddress() 返回此伺服器套接字的本地地址。
  • int getLocalPort() 返回此套接字在其上偵聽的埠。
  • SocketAddress getLocalSocketAddress() 返回此套接字繫結的端點的地址,如果尚未繫結則返回 null。
  • int getReceiveBufferSize() 獲取此 ServerSocket 的 SO_RCVBUF 選項的值,該值是將用於從此 ServerSocket 接受的套接字的建議緩衝區大小。
  • boolean getReuseAddress() 測試是否啟用 SO_REUSEADDR。
  • int getSoTimeout() 獲取 SO_TIMEOUT 的設定。
  • protected void implAccept(Socket s) ServerSocket 的子類使用此方法重寫 accept() 以返回它們自己的套接字子類。
  • boolean isBound() 返回 ServerSocket 的繫結狀態。
  • boolean isClosed() 返回 ServerSocket 的關閉狀態。
  • void setPerformancePreferences(int connectionTime, int latency, int bandwidth) 設定此 ServerSocket 的效能首選項。
  • void setReceiveBufferSize(int size) 為從此 ServerSocket 接受的套接字的 SO_RCVBUF 選項設定預設建議值。
  • void setReuseAddress(boolean on) 啟用/禁用 SO_REUSEADDR 套接字選項。
  • static void setSocketFactory(SocketImplFactory fac) 為應用程式設定伺服器套接字實現工廠。
  • void setSoTimeout(int timeout) 通過指定超時值啟用/禁用 SO_TIMEOUT,以毫秒為單位。
  • String toString() 作為 String 返回此套接字的實現地址和實現埠。

Socket

構造方法

  • Socket() 通過系統預設型別的 SocketImpl 建立未連線套接字
  • Socket(InetAddress address, int port) 建立一個流套接字並將其連線到指定IP地址的指定埠號
  • Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 建立一個套接字並將其連線到指定遠端地址上的指定遠端埠。
  • Socket(Proxy proxy) 建立一個未連線的套接字並指定代理型別(如果有),該代理不管其他設定如何都應被使用。
  • Socket(SocketImpl impl) 使用使用者指定的 SocketImpl 建立一個未連線 Socket。
  • Socket(String host, int port) 建立一個流套接字並將其連線到指定主機上的指定埠號。
  • Socket(String host, int port, InetAddress localAddr, int localPort) 建立一個套接字並將其連線到指定遠端主機上的指定遠端埠。

常用方法

  • void bind(SocketAddress bindpoint) 將套接字繫結到本地地址。
  • void close() 關閉此套接字。
  • void connect(SocketAddress endpoint) 將此套接字連線到伺服器。
  • void connect(SocketAddress endpoint, int timeout) 將此套接字連線到伺服器,並指定一個超時值
  • SocketChannel getChannel() 返回與此資料報套接字關聯的唯一 SocketChannel 物件(如果有)。
  • InetAddress getInetAddress() 返回套接字連線的地址。
  • InputStream getInputStream() 返回此套接字的輸入流。
  • boolean getKeepAlive() 測試是否啟用 SO_KEEPALIVE。
  • InetAddress getLocalAddress() 獲取套接字繫結的本地地址。
  • int getLocalPort() 返回此套接字繫結到的本地埠。
  • SocketAddress getLocalSocketAddress() 返回此套接字繫結的端點的地址,如果尚未繫結則返回 null。
  • boolean getOOBInline() 測試是否啟用 OOBINLINE。
  • OutputStream getOutputStream() 返回此套接字的輸出流。
  • int getPort() 返回此套接字連線到的遠端埠。
  • int getReceiveBufferSize() 獲取此 Socket 的 SO_RCVBUF 選項的值,該值是平臺在 Socket 上輸入時使用的緩衝區大小。
  • SocketAddress getRemoteSocketAddress() 返回此套接字連線的端點的地址,如果未連線則返回 null。
  • boolean getReuseAddress() 測試是否啟用 SO_REUSEADDR。
  • int getSendBufferSize() 獲取此 Socket 的 SO_SNDBUF 選項的值,該值是平臺在 Socket 上輸出時使用的緩衝區大小。
  • int getSoLinger() 返回 SO_LINGER 的設定。
  • int getSoTimeout() 返回 SO_TIMEOUT 的設定。
  • boolean getTcpNoDelay() 測試是否啟用 TCP_NODELAY。
  • int getTrafficClass() 為從此 Socket 上傳送的包獲取 IP 頭中的流量類別或服務型別。
  • boolean isBound() 返回套接字的繫結狀態。
  • boolean isClosed() 返回套接字的關閉狀態。
  • boolean isConnected() 返回套接字的連線狀態。
  • boolean isInputShutdown() 返回是否關閉套接字連線的半讀狀態 (read-half) 。
  • boolean isOutputShutdown() 返回是否關閉套接字連線的半寫狀態 (write-half) 。
  • void sendUrgentData(int data) 在套接字上傳送一個緊急資料位元組。
  • void setKeepAlive(boolean on) 啟用/禁用 SO_KEEPALIVE。
  • void setOOBInline(boolean on) 啟用/禁用 OOBINLINE(TCP 緊急資料的接收者) 預設情況下,此選項是禁用的,即在套接字上接收的 TCP 緊急資料被靜默丟棄。
  • void setPerformancePreferences(int connectionTime, int latency, int bandwidth) 設定此套接字的效能偏好。
  • void setReceiveBufferSize(int size) 將此 Socket 的 SO_RCVBUF 選項設定為指定的值。
  • void setReuseAddress(boolean on) 啟用/禁用 SO_REUSEADDR 套接字選項。
  • void setSendBufferSize(int size) 將此 Socket 的 SO_SNDBUF 選項設定為指定的值。
  • static void setSocketImplFactory(SocketImplFactory fac) 為應用程式設定客戶端套接字實現工廠。
  • void setSoLinger(boolean on, int linger) 啟用/禁用具有指定逗留時間(以秒為單位)的 SO_LINGER。
  • void setSoTimeout(int timeout) 啟用/禁用帶有指定超時值的 SO_TIMEOUT,以毫秒為單位。
  • void setTcpNoDelay(boolean on) 啟用/禁用 TCP_NODELAY(啟用/禁用 Nagle 演算法)。
  • void setTrafficClass(int tc) 為從此 Socket 上傳送的包在 IP 頭中設定流量類別 (traffic class) 或服務型別八位組 (type-of-service octet) 。
  • void shutdownInput() 此套接字的輸入流置於“流的末尾”。
  • void shutdownOutput() 禁用此套接字的輸出流。
  • String toString() 將此套接字轉換為 String。

DatagramSocket

構造方法

  • DatagramSocket() 構造資料報套接字並將其繫結到本地主機上任何可用的埠。
  • DatagramSocket(int port) 建立資料報套接字並將其繫結到本地主機上的指定埠。
  • DatagramSocket(int port, InetAddress laddr) 繫結到指定的本地地址。
  • DatagramSocket(SocketAddress bindaddr) 繫結到指定的本地套接字地址。
  • protected DatagramSocket(DatagramSocketImpl impl) 建立帶有指定impl 的未繫結資料報套接字

常用方法

  • void bind(SocketAddress addr) 將此 DatagramSocket 繫結到特定的地址和埠。
  • void close() 關閉此資料報套接字。
  • void connect(InetAddress address, int port) 將套接字連線到此套接字的遠端地址。
  • void connect(SocketAddress addr) 將此套接字連線到遠端套接字地址(IP 地址 + 埠號)。
  • void disconnect() 斷開套接字的連線。
  • boolean getBroadcast() 檢測是否啟用了 SO_BROADCAST。
  • DatagramChannel getChannel() 返回與此資料報套接字關聯的唯一 DatagramChannel 物件(如果有)。
  • InetAddress getInetAddress() 返回此套接字連線的地址。
  • InetAddress getLocalAddress() 獲取套接字繫結的本地地址。
  • int getLocalPort() 返回此套接字繫結的本地主機上的埠號。
  • SocketAddress getLocalSocketAddress() 返回此套接字繫結的端點的地址,如果尚未繫結則返回 null。
  • int getPort() 返回此套接字的埠。
  • int getReceiveBufferSize() 獲取此 DatagramSocket 的 SO_RCVBUF 選項的值,該值是平臺在 DatagramSocket 上輸入時使用的緩衝區大小。
  • SocketAddress getRemoteSocketAddress() 返回此套接字連線的端點的地址,如果未連線則返回 null。
  • boolean getReuseAddress() 檢測是否啟用了 SO_REUSEADDR。
  • int getSendBufferSize() 獲取此 DatagramSocket 的 SO_SNDBUF 選項的值,該值是平臺在 DatagramSocket 上輸出時使用的緩衝區大小。
  • int getSoTimeout() 獲取 SO_TIMEOUT 的設定。
  • int getTrafficClass() 為從此 DatagramSocket 上傳送的包獲取 IP 資料報頭中的流量類別或服務型別
  • boolean isBound() 返回套接字的繫結狀態。
  • boolean isClosed() 返回是否關閉了套接字。
  • boolean isConnected() 返回套接字的連線狀態。
  • void receive(DatagramPacket p) 從此套接字接收資料報包。
  • void send(DatagramPacket p) 從此套接字傳送資料報包。
  • void setBroadcast(boolean on) 啟用/禁用 SO_BROADCAST。
  • static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 為應用程式設定資料報套接字實現工廠
  • void setReceiveBufferSize(int size) 將此DatagramSocket的 SO_RCVBUF 選項設定為指定的值
  • void setReuseAddress(boolean on) 啟用/禁用 SO_REUSEADDR 套接字選項。
  • void setSendBufferSize(int size) 將此 DatagramSocket 的 SO_SNDBUF 選項設定為指定的值
  • void setSoTimeout(int timeout) 啟用/禁用帶有指定超時值的 SO_TIMEOUT,以毫秒為單位。
  • void setTrafficClass(int tc) 為從此 DatagramSocket 上傳送的資料報在 IP 資料報頭中設定流量類別 (traffic class) 或服務型別八位組 (type-of-service octet)。

DatagramPacket

構造方法
接收

  • DatagramPacket(byte[] buf, int length) 構造 DatagramPacket,用來接收長度為 length 的資料包。
  • DatagramPacket(byte[] buf, int offset, int length) 構造 DatagramPacket,用來接收長度為 length 的包,在緩衝區中指定了偏移量。

傳送到 InetAddress

  • DatagramPacket(byte[] buf, int length, InetAddress address, int port) 構造資料報包,用來將長度為 length 的包 buf 傳送指定主機address上的指定埠號port
  • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 構造資料報包,用來將長度為 length 偏移量為 offset 的包傳送到指定主機上的指定埠號。

傳送到 SocketAddress

  • DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 構造資料報包,用來將長度為 length 偏移量為 offset 的包傳送到指定主機上的指定埠號。
  • DatagramPacket(byte[] buf, int length, SocketAddress address) 構造資料報包,用來將長度為 length 的包傳送到指定主機上的指定埠號。

常用方法
get 方法

  • InetAddress getAddress() 返回某臺機器的 IP 地址,此資料報將要發往該機器或者是從該機器接收到的
  • byte[] getData() 返回資料緩衝區。
  • int getLength() 返回將要傳送或接收到的資料的長度。
  • int getOffset() 返回將要傳送或接收到的資料的偏移量。
  • int getPort() 返回某臺遠端主機的埠號,此資料報將要發往該主機或者是從該主機接收到的。
  • SocketAddress getSocketAddress() 獲取要將此包傳送到的或發出此資料報的遠端主機的 SocketAddress

set 方法

  • void setAddress(InetAddress iaddr) 設定要將此資料報發往的那臺機器的 IP 地址。
  • void setData(byte[] buf) 為此包設定資料緩衝區。
  • void setData(byte[] buf, int offset, int length) 為此包設定資料緩衝區。
  • void setLength(int length) 為此包設定長度。
  • void setPort(int iport) 設定要將此資料報發往的遠端主機上的埠號。
  • void setSocketAddress(SocketAddress address) 設定要將此資料報發往的遠端主機的 SocketAddress(通常為 IP 地址 + 埠號)。

2018-11-23

相關推薦

TCP UDP Socket 即時通訊 API 示例

Markdown版本筆記 我的GitHub首頁 我的部落格 我的微信 我的郵箱 TCP Socket 即時通訊 API 示例 目錄 TCP 案例 SocketActivity public class SocketActivity extends ListA

TCP Socket 即時通訊 API 示例

sin puts 簡單的 rri lin .cn 構造 live system Markdown版本筆記 我的GitHub首頁 我的博客 我的微信 我的郵箱 MyAndroidBlogs baiqiantao baiqiantao

Linux網路程式設計之Tcp/Udp socket檔案傳輸示例

本文所述示例程式是基於Linux平臺的socket網路程式設計,實現檔案傳輸功能。該示例是基於TCP流協議實現的socket網路檔案傳輸程式。採用C語言編寫。最終能夠實現傳輸任何格式檔案的檔案傳輸程式。 具體實現程式碼如下: /***********************

Socket,TCP,UDP,HTTP基本通訊原理和OC版本Demo

非常通俗的例子->寄快遞 TCP和UDP是傳輸方式—> 例如空運,輪渡,陸運 HTTP,XMPP則是資料傳輸格式協議 –> 寄送的東西(吃的,用的,玩的。。。) socket理解為傳輸層和應用層之前的抽象物件,通過對TCP/IP傳世方式的封

Vue與Node.js通過socket.io通訊示例

#一、Node中socket.io基礎 1、是什麼 Socket.IO類庫,是在伺服器和瀏覽器之間提供一個共享介面,其可以用於實現以下幾種通訊方式: HTML5中的WebSocket通訊 Flash中使用的WebSocket通訊 XHR輪詢 JSONP

C語言 AF_UNIX tcp/udp socket例項

https://blog.csdn.net/shanzhizi/article/details/16882087   ========================tcp 方式============================ 伺服器端: //s_unix.

Nodejs入門基礎(socket即時通訊

socket.html--前端頁面,可以輸入內容傳遞給index.js進行接收index.js--獲取前端頁面的資訊並處理返回值給前端頁面socket.html   <!DOCTYPE html> <html lang="en"> <head>

TCP UDP Socket

TCP(Transmission Control Protocol,傳輸控制協議) TCP是基於連結的協議,也就是說,在正式收發資料前,必須和對方建立可靠的連結。一個TCP連線必須要經過三次”對話”才能建立起來,其中的過程非常複雜,我們這裡只做簡單,行象的介紹,你只要做到能夠理解這個過程即可。 三

網路協議中HTTP,TCP,UDP,Socket,WebSocket的優缺點/區別

先說一下網路的層級:由下往上分為 物理層、資料鏈路層、網路層、傳輸層、會話層、表示層和應用層 1、TCP和UDP TCP:是面向連線的一種傳輸控制協議。屬於傳輸層協議。TCP連線之後,客戶端和伺服器可以互相傳送和接收訊息,在客戶端或者伺服器沒有主動斷開之前,連線一直存在屬於長

【如何快速的開發一個完整的iOS直播app】(搭建Socket即時通訊伺服器)

發個廣告:ios開發兩年了,一步步走來  關注公眾號一起進步 前言 在直播中,聊天和發禮物,需要用到及時通訊技術,市面上的App大多數採用的都是第三方SDK,融雲,環信等,但是本例子採用websocket搭建及時通訊伺服器。 如果喜歡我的文章,可以關注我微博:袁崢Se

TCP/UDP,SOCKET,HTTP,FTP協議簡析

(一)TCP/UDP,SOCKET,HTTP,FTP簡析 TCP/IP是個協議組,可分為三個層次:網路層、傳輸層和應用層: 網路層:IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議 傳輸層:TCP協議與UDP協議 應用層:FTP、HTTP、TE

TCP UDP Socket 網路程式設計總體步驟總結

【TCP】 1. 伺服器端     1)建立套接字create;     2)繫結埠號bind;     3)監聽連線listen;     4)接受連線請求accept,並返回新的套接字;     5

HTTP,TCP,UDP,SOCKET整理

1.HTTP HTTP是無狀態,“請求-響應”式,短連線通訊協議。伺服器處於監聽狀態,接收到客戶端請求後建立連線。客戶端向服務端傳送資訊,服務端回覆,然後斷開連結。客戶端如果不發出請求,服務端無法直接

HTTP TCP UDP Socket 關係的幾個經典圖

Posted on 2015-02-17 16:52 蟈蟈俊 閱讀(2686) 評論(0) 編輯 收藏 從上圖可以看到,TCP/IP是個協議組,可分為三個層次:網路層、傳輸層和應用層。  在網路層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議

java網路通訊Socket通訊TCP/UDP

網路通訊三要素:協議,IP,埠。七層協議。 package com.qianfeng.test; /* * 網路程式設計基礎: * 網路的通訊:三要素:協議,IP,埠 * 1.IP:在網路上唯一的標記一臺主機 127.0.0.1 :保留地址/本地地址 java

[原始碼和文件分享]使用同一資料庫基於TCP Socket和Websocket實現的相互即時通訊系統

摘 要 隨著網路通訊和計算機技術的發展,人們越來越希望能夠即時傳送和接收網際網路訊息。與此同時隨著網際網路的發展在HTML5中提出了websocket協議,能更好的節省伺服器資源和頻寬並且伺服器和瀏覽器能夠雙向實時通訊。為了能讓使用者體驗傳統客戶端和web帶來的即時通訊結合的超爽體驗,本次畢業設

網路通訊協議和 tcp udpsocket 中的區別 網路通訊協議

  網路通訊協議   本節主要內容: 1.osi七層模型 2.socket

Socket程式設計(非同步通訊)(Tcp,Udp

上一章主要展示了Socket的Tcp\Udp兩種協議下的基本通訊方式,屬於同步通訊。至於一個伺服器對應多個客戶端,或者對應多個請求,我們採用的是多執行緒的方式來解決此問題。然而本章節我們將有更好的方式去實現它:Socket在Tcp\Udp兩種協議下的非同步通訊方式。 基

Socket 通訊原理(Android客戶端和伺服器以TCP&&UDP方式互通)

ZERO、前言 有關通訊原理內容是在網上或百科整理得到,程式碼部分為本人所寫,如果不當,還望指教。 一、Socket通訊簡介  Android與伺服器的通訊方式主要有兩種,一是Http通訊,一是Socket通訊。兩者的最大差異在於,http連線使用的是“請求—響應方式

Java Socket通訊TCP/UDP實現

記得上一次接觸socket這一塊還是在大三抓耳撓腮的整畢設的時候,兩年後的今天又用到了它,那就把Socket實現組播什麼的做一個記錄吧。 TcpServer public class T