Java基于UDP協(xié)議的聊天室功能
UDP簡(jiǎn)述
UDP(User Datagram Protocol)協(xié)議是Internet 協(xié)議集支持的一個(gè)無(wú)連接的傳輸協(xié)議,中文名為用戶數(shù)據(jù)報(bào)協(xié)議。它為應(yīng)用程序提供了一種無(wú)需建立連接就可以發(fā)送封裝的 IP 數(shù)據(jù)報(bào)的方法。
Internet 的傳輸層有兩個(gè)主要協(xié)議,互為補(bǔ)充。無(wú)連接的是 UDP,它除了給應(yīng)用程序發(fā)送數(shù)據(jù)包功能并允許它們?cè)谒璧膶哟紊霞軜?gòu)自己的協(xié)議之外,幾乎沒(méi)有做什么特別的事情。面向連接的是TCP,該協(xié)議幾乎做了所有的事情。“when in trouble , use TCP”。
那么今天講講如何使用UDP協(xié)議構(gòu)建一個(gè)簡(jiǎn)單的小型聊天室。ChatA先發(fā)起聊天,然后ChatB才能在控制臺(tái)輸入聊天內(nèi)容。如果想結(jié)束聊天可以輸入over,當(dāng)一方結(jié)束聊天,另一方也將結(jié)束聊天。
ChatA類(客戶端A):
代碼展示如下:
package my.demo; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; import java.util.Scanner; //客戶端A public class ChatA { ?? ?public static void main(String[] args) { ?? ??? ?//控制臺(tái)輸入 ?? ??? ?Scanner input = new Scanner(System.in); ?? ??? ? ?? ??? ?// 創(chuàng)建基于UDP協(xié)議的DatagramSocket對(duì)象 ?? ??? ?// 客戶端A監(jiān)聽(tīng)8888端口 ?? ??? ?try (DatagramSocket socket = new DatagramSocket(8888)) { ?? ??? ??? ?//封裝成DatagramPacket對(duì)象(數(shù)據(jù)包) ?? ??? ??? ?DatagramPacket sendPacket = new DatagramPacket( ?? ??? ??? ??? ??? ?new byte[1024], ?? ??? ??? ??? ??? ?1024, ?? ??? ??? ??? ??? ?new InetSocketAddress("192.168.254.105", 7777));//對(duì)方的IP地址和端口號(hào) ?? ??? ??? ?DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024); ?? ??? ??? ?while (true) { ?? ??? ??? ??? ?// 發(fā)送數(shù)據(jù)包 ?? ??? ??? ??? ?System.out.print("【客戶端A】(你)說(shuō): "); ?? ??? ??? ??? ?String sendContent = input.nextLine(); ?? ??? ??? ??? ?sendPacket.setData(sendContent.getBytes()); ?? ??? ??? ??? ?socket.send(sendPacket); ?? ??? ??? ??? ?if (sendContent.equals("over")) { ?? ??? ??? ??? ??? ?System.out.println("你退出了聊天......"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?// 接收數(shù)據(jù)包 ?? ??? ??? ??? ?socket.receive(receivePacket); ?? ??? ??? ??? ?String receiveContent = new String( ?? ??? ??? ??? ??? ??? ?receivePacket.getData(), ? //數(shù)據(jù) ?? ??? ??? ??? ??? ??? ?receivePacket.getOffset(), //讀取位置 ?? ??? ??? ??? ??? ??? ?receivePacket.getLength());//長(zhǎng)度 ?? ??? ??? ??? ?if (receiveContent.equals("over")) { ?? ??? ??? ??? ??? ?System.out.println("對(duì)方退出了聊天......"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?System.out.println("【客戶端B】(他)說(shuō): " + receiveContent); ?? ??? ??? ?} ?? ??? ?} catch (SocketException e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} catch (IOException e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} ?? ?} }
ChatB類(客戶端B):
代碼展示如下:
package my.demo; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; import java.util.Scanner; //客戶端B public class ChatB { ?? ?public static void main(String[] args) { ?? ??? ?// 控制臺(tái)輸入 ?? ??? ?Scanner input = new Scanner(System.in); ?? ??? ?try (// 客戶端B監(jiān)聽(tīng)7777端口 ?? ??? ??? ??? ?DatagramSocket socket = new DatagramSocket(7777)) { ?? ??? ??? ?// 封裝成DatagramPacket對(duì)象(數(shù)據(jù)包) ?? ??? ??? ?DatagramPacket sendPacket = new DatagramPacket(new byte[1024], 1024, ?? ??? ??? ??? ??? ?new InetSocketAddress("192.168.254.105", 8888));// 對(duì)方的IP地址和端口號(hào) ?? ??? ??? ?DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024); ?? ??? ??? ?while (true) { ?? ??? ??? ??? ?// 接收數(shù)據(jù)包 ?? ??? ??? ??? ?socket.receive(receivePacket); ?? ??? ??? ??? ?String receiveContent = new String(receivePacket.getData(), receivePacket.getOffset(), ?? ??? ??? ??? ??? ??? ?receivePacket.getLength()); ?? ??? ??? ??? ?if (receiveContent.equals("over")) { ?? ??? ??? ??? ??? ?System.out.println("對(duì)方退出了聊天......"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?System.out.println("【客戶端A】(他)說(shuō): " + receiveContent); ?? ??? ??? ??? ?// 發(fā)送數(shù)據(jù)包 ?? ??? ??? ??? ?System.out.print("【客戶端B】(你)說(shuō): "); ?? ??? ??? ??? ?String sendContent = input.nextLine(); ?? ??? ??? ??? ?sendPacket.setData(sendContent.getBytes()); ?? ??? ??? ??? ?socket.send(sendPacket); ?? ??? ??? ??? ?if (sendContent.equals("over")) { ?? ??? ??? ??? ??? ?System.out.println("你退出了聊天......"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} catch (SocketException e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} catch (IOException e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} ?? ?} }
運(yùn)行結(jié)果展示:
1.運(yùn)行ChatA和ChatB(不分先后順序)
2. ChatA先發(fā)起聊天:
在控制臺(tái)輸入:你好
ChatB顯示內(nèi)容:
3. ChatB向ChatA發(fā)起聊天:
ChatA顯示內(nèi)容:
4. 輸入over結(jié)束聊天:
ChatA:
ChatB:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
eclipse連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)用戶注冊(cè)登錄功能
這篇文章主要介紹了eclipse連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)用戶注冊(cè)登錄功能的相關(guān)資料,需要的朋友可以參考下2021-01-01java啟動(dòng)jar包設(shè)置啟動(dòng)參數(shù)的實(shí)現(xiàn)
本文主要介紹了java啟動(dòng)jar包設(shè)置啟動(dòng)參數(shù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Shiro整合Springboot和redis,jwt過(guò)程中的錯(cuò)誤shiroFilterChainDefinition問(wèn)
這篇文章主要介紹了Shiro整合Springboot和redis,jwt過(guò)程中的錯(cuò)誤shiroFilterChainDefinition問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04java servlet 幾種頁(yè)面跳轉(zhuǎn)的方法
java servlet 幾種頁(yè)面跳轉(zhuǎn)的方法,需要的朋友可以參考一下2013-04-04基于Java代碼實(shí)現(xiàn)判斷春節(jié)、端午節(jié)、中秋節(jié)等法定節(jié)假日的方法
這篇文章主要介紹了基于Java代碼實(shí)現(xiàn)判斷春節(jié)、端午節(jié)、中秋節(jié)等法定節(jié)假日的方法 的相關(guān)資料,需要的朋友可以參考下2016-01-01PowerJob的DesignateServer工作流程源碼解讀
這篇文章主要介紹了PowerJob的DesignateServer工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01詳解Java8如何使用Lambda表達(dá)式進(jìn)行比較
Lambda表達(dá)式,也可稱為閉包,是java8的新特性,作用是取代大部分內(nèi)部類,優(yōu)化java代碼結(jié)構(gòu),讓代碼變得更加簡(jiǎn)潔緊湊。本文將利用Lambda表達(dá)式進(jìn)行排序比較,需要的可以參考一下2022-01-01