java socket 之Udp通過(guò)doc窗口實(shí)現(xiàn)簡(jiǎn)單的聊天

  • 實(shí)現(xiàn)的效果如下


    chatDemo
  • udp和tcp的特點(diǎn)

udp
1、將數(shù)據(jù)封裝在數(shù)據(jù)包中,不需要建立連接,面向無(wú)連接
2、每個(gè)數(shù)據(jù)包的大小限制在64k內(nèi)
3、因?yàn)闊o(wú)連接,是不可靠協(xié)議
4、速度快
tpc
1、建立連接,形成傳輸數(shù)據(jù)的通道
2、在連接中進(jìn)行大數(shù)據(jù)量傳輸
3、通過(guò)三次握手完成連接,是可靠協(xié)議
4、必須建立連接,效率會(huì)稍低
  • 以下是通過(guò)udp進(jìn)行通訊的,廢話不多說(shuō),直接上代碼

import java.net.*;
import java.io.*;

/*
聊天程序
有發(fā)送端和接收端
采用多線程,一個(gè)控制發(fā)送,一個(gè)控制接收
并采用鍵盤(pán)錄入的方式
這里的異常我就直接拋了
*/
class ChatDemo{
    public static void main(String[] args) throws Exception{
        //創(chuàng)建udp服務(wù)
        DatagramSocket sendSocket = new DatagramSocket();
        DatagramSocket receSocket = new DatagramSocket(10002);
        //開(kāi)啟線程
        new Thread(new Send(sendSocket)).start();
        new Thread(new Rece(receSocket)).start();
    }
}

/*
發(fā)送端
實(shí)現(xiàn)步驟:
1、創(chuàng)建udp socket 服務(wù)
2、定義數(shù)據(jù)包,并將數(shù)據(jù)封裝到數(shù)據(jù)包中。
3、通過(guò)socket服務(wù)的發(fā)送方法,將數(shù)據(jù)發(fā)送出去。
4、關(guān)閉資源
*/
class Send implements Runnable{
    
    private DatagramSocket ds;
    public Send(DatagramSocket ds){
        this.ds = ds;
    }
    
    public void run(){
        try{
            //鍵盤(pán)錄入
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            
            while((line = bufr.readLine()) != null){//這里的bufr.readLine()其實(shí)是一個(gè)阻塞方法,等待輸入結(jié)束后才繼續(xù)執(zhí)行下面的代碼
                if("886".equals(line)){
                    break;
                }
                //獲取到鍵盤(pán)錄入數(shù)據(jù),定義數(shù)據(jù)包,并將數(shù)據(jù)封裝到數(shù)據(jù)包中,指定要發(fā)送到哪臺(tái)主機(jī)的哪個(gè)端口上
                //這里只用本機(jī)做測(cè)試,所以指定的ip地址是本地的,端口隨便起,不要超過(guò)指定的大小即可
                byte[] buf = line.getBytes();
                DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.3.107"),10002);
                //發(fā)送數(shù)據(jù)包
                ds.send(dp);
            }
        }catch(Exception e){
            throw new RuntimeException("send client error");
        }finally{
            if(ds != null){
                try{
                    //關(guān)閉資源
                    ds.close();
                }catch(Exception e){}
            }
        }
    }
}


/*
接收端
實(shí)現(xiàn)步驟:
1、創(chuàng)建udp socket ,建立端點(diǎn)。通常會(huì)監(jiān)聽(tīng)一個(gè)端口,其實(shí)就是給這個(gè)接收網(wǎng)絡(luò)應(yīng)用程序定義數(shù)字標(biāo)識(shí),
    為了方便明確哪些數(shù)據(jù)過(guò)來(lái)該應(yīng)用程序可以處理
2、定義數(shù)據(jù)包,因?yàn)橐鎯?chǔ)接收到的字節(jié)數(shù)據(jù),
    因?yàn)閿?shù)據(jù)包中有更多功能提取字節(jié)數(shù)據(jù)中的不同數(shù)據(jù)信息。
3、通過(guò)socket服務(wù)的receive方法將收到的數(shù)據(jù)存入已定義好的數(shù)據(jù)包中。
4、通過(guò)數(shù)據(jù)包對(duì)象的特有方法,將這些不同的數(shù)據(jù)獲取到并打印在控制臺(tái)。
5、關(guān)閉資源
*/
class Rece implements Runnable{
    
    private DatagramSocket ds;
    public Rece(DatagramSocket ds){
        this.ds = ds;
    }
    
    public void run(){
        try{
            
            while(true){
                //定義個(gè)數(shù)組存儲(chǔ)接收到的數(shù)據(jù)
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf,buf.length);
                
                //通過(guò)receive方法將收到的數(shù)據(jù)存入數(shù)據(jù)包中
                //這里的receive是一個(gè)阻塞方法,會(huì)一直停在這,直到有數(shù)據(jù)來(lái)了才會(huì)被喚醒繼續(xù)執(zhí)行下面代碼
                ds.receive(dp);
                
                //通過(guò)數(shù)據(jù)包的方法獲取其中的數(shù)據(jù)
                String ip = dp.getAddress().getHostAddress();
                String data = new String(dp.getData(),0,dp.getLength());
                //這里只打印ip和data
                System.out.println(ip + "-----" + data);
            }
            
        }catch(Exception e){
            throw new RuntimeException("receive server error");
        }finally{
            if(ds != null){
                try{
                    ds.close();
                }catch(Exception e){}
            }
        }
    }
}
  • 如何運(yùn)行
1、將上面的代碼復(fù)制粘貼到你的文本編輯器,并以ChatDemo.java命名,存到你想存的文件夾當(dāng)中
2、配置好jdk和相對(duì)應(yīng)的環(huán)境變量
3、調(diào)出cmd控制臺(tái),cd到ChatDemo.java文件目錄下
4、輸入"javac ChatDemo.java"進(jìn)行編譯
5、編譯通過(guò)后再輸入"java ChatDemo"運(yùn)行
6、就可以看到上圖中的界面了,可以隨便測(cè)試了。
  • 獲取本機(jī)ip地址
因?yàn)槭窃谧约旱臋C(jī)器運(yùn)行,所以你要修改代碼中的ip地址。
獲取本機(jī)ip地址方式:通過(guò)cmd控制臺(tái),輸入"ipconfig"按回車(chē),你看到的ipv4就是你的本機(jī)代碼了,右鍵選中按回車(chē)進(jìn)行復(fù)制即可。
  • 用到的api,參考android官方文檔
    DatagramSocket
    DatagramPacket
    InetAddress

  • 由于代碼中的解釋已經(jīng)很清楚了,在這里就不做解釋了。后期會(huì)出個(gè)Tcp的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,179評(píng)論 25 708
  • 11.1 引言 UDP是一個(gè)簡(jiǎn)單的面向數(shù)據(jù)報(bào)的運(yùn)輸層協(xié)議:進(jìn)程的每個(gè)輸出操作都正好產(chǎn)生一個(gè)UDP數(shù)據(jù)報(bào),并組裝成一...
    張芳濤閱讀 2,971評(píng)論 1 6
  • 轉(zhuǎn)眼間,已經(jīng)過(guò)去啦7天,明天也許我們將是最后一次一起做任務(wù),在這7天,我覺(jué)得我是最幸運(yùn)的,因?yàn)樵谧蠲赖臅r(shí)候遇見(jiàn)了你...
    唐小雨_0ed9閱讀 349評(píng)論 0 0
  • 非暴力實(shí)踐篇這本書(shū)講的大多數(shù)是案例,在遇到問(wèn)題時(shí)要怎么說(shuō)才能了解對(duì)方的需要。當(dāng)我們?cè)谑褂梅潜┝贤ㄕZ(yǔ)言時(shí),如果對(duì)方...
    無(wú)敵羅小美閱讀 151評(píng)論 0 0
  • 未過(guò)龍門(mén)心不甘, 矢志輪回比金堅(jiān)。 怒翻烈滾喉舌過(guò), 來(lái)世云騰江海翻。
    溫情永久閱讀 643評(píng)論 10 3

友情鏈接更多精彩內(nèi)容