-
實現(xiàn)的效果如下
chatDemo udp和tcp的特點
udp
1、將數(shù)據(jù)封裝在數(shù)據(jù)包中,不需要建立連接,面向無連接
2、每個數(shù)據(jù)包的大小限制在64k內(nèi)
3、因為無連接,是不可靠協(xié)議
4、速度快
tpc
1、建立連接,形成傳輸數(shù)據(jù)的通道
2、在連接中進(jìn)行大數(shù)據(jù)量傳輸
3、通過三次握手完成連接,是可靠協(xié)議
4、必須建立連接,效率會稍低
- 以下是通過udp進(jìn)行通訊的,廢話不多說,直接上代碼
import java.net.*;
import java.io.*;
/*
聊天程序
有發(fā)送端和接收端
采用多線程,一個控制發(fā)送,一個控制接收
并采用鍵盤錄入的方式
這里的異常我就直接拋了
*/
class ChatDemo{
public static void main(String[] args) throws Exception{
//創(chuàng)建udp服務(wù)
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10002);
//開啟線程
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
}
/*
發(fā)送端
實現(xiàn)步驟:
1、創(chuàng)建udp socket 服務(wù)
2、定義數(shù)據(jù)包,并將數(shù)據(jù)封裝到數(shù)據(jù)包中。
3、通過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{
//鍵盤錄入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine()) != null){//這里的bufr.readLine()其實是一個阻塞方法,等待輸入結(jié)束后才繼續(xù)執(zhí)行下面的代碼
if("886".equals(line)){
break;
}
//獲取到鍵盤錄入數(shù)據(jù),定義數(shù)據(jù)包,并將數(shù)據(jù)封裝到數(shù)據(jù)包中,指定要發(fā)送到哪臺主機的哪個端口上
//這里只用本機做測試,所以指定的ip地址是本地的,端口隨便起,不要超過指定的大小即可
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){}
}
}
}
}
/*
接收端
實現(xiàn)步驟:
1、創(chuàng)建udp socket ,建立端點。通常會監(jiān)聽一個端口,其實就是給這個接收網(wǎng)絡(luò)應(yīng)用程序定義數(shù)字標(biāo)識,
為了方便明確哪些數(shù)據(jù)過來該應(yīng)用程序可以處理
2、定義數(shù)據(jù)包,因為要存儲接收到的字節(jié)數(shù)據(jù),
因為數(shù)據(jù)包中有更多功能提取字節(jié)數(shù)據(jù)中的不同數(shù)據(jù)信息。
3、通過socket服務(wù)的receive方法將收到的數(shù)據(jù)存入已定義好的數(shù)據(jù)包中。
4、通過數(shù)據(jù)包對象的特有方法,將這些不同的數(shù)據(jù)獲取到并打印在控制臺。
5、關(guān)閉資源
*/
class Rece implements Runnable{
private DatagramSocket ds;
public Rece(DatagramSocket ds){
this.ds = ds;
}
public void run(){
try{
while(true){
//定義個數(shù)組存儲接收到的數(shù)據(jù)
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//通過receive方法將收到的數(shù)據(jù)存入數(shù)據(jù)包中
//這里的receive是一個阻塞方法,會一直停在這,直到有數(shù)據(jù)來了才會被喚醒繼續(xù)執(zhí)行下面代碼
ds.receive(dp);
//通過數(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){}
}
}
}
}
- 如何運行
1、將上面的代碼復(fù)制粘貼到你的文本編輯器,并以ChatDemo.java命名,存到你想存的文件夾當(dāng)中
2、配置好jdk和相對應(yīng)的環(huán)境變量
3、調(diào)出cmd控制臺,cd到ChatDemo.java文件目錄下
4、輸入"javac ChatDemo.java"進(jìn)行編譯
5、編譯通過后再輸入"java ChatDemo"運行
6、就可以看到上圖中的界面了,可以隨便測試了。
- 獲取本機ip地址
因為是在自己的機器運行,所以你要修改代碼中的ip地址。
獲取本機ip地址方式:通過cmd控制臺,輸入"ipconfig"按回車,你看到的ipv4就是你的本機代碼了,右鍵選中按回車進(jìn)行復(fù)制即可。
用到的api,參考android官方文檔
DatagramSocket
DatagramPacket
InetAddress由于代碼中的解釋已經(jīng)很清楚了,在這里就不做解釋了。后期會出個Tcp的