Udp編程的一些練習:
前面我們學習了Udp編程的引入,寫的代碼有點繁瑣,現在我們直接優化改進一下:
package com.westos.Udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 優化Udp編程
*
*/
public class SendDome {
public static void main(String[] args) throws IOException {
//1)創建Socket對象
DatagramSocket ds=new DatagramSocket();
//2)創建數據並打包
byte[] bys = "我來了,北京".getBytes();
DatagramPacket dp=new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.43.204"),12345);
//3)發生數據報包
ds.send(dp);
//4)關閉資源
ds.close();
}
}
package com.westos.Udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDome {
public static void main(String[] args) throws IOException {
//1)創建Socket對象,接收端的Socket對象必須有發送端相對應的端口號
DatagramSocket ds=new DatagramSocket(12345);
//2)創建數據報包
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys, bys.length);
//3)接收數據報包
ds.receive(dp);
//4)實時分析數據
String data=new String(dp.getData(),0,dp.getLength());
String ip=dp.getAddress().getHostAddress();
//5)輸出數據
System.out.println("from"+ip+"data is"+data);
//6)關閉數據
ds.close();
}
}
以上的案例只是可以實現一句話的傳輸,那麼當我們想要進行多句話的傳輸時應該怎麼改進呢?
分析這裏講運用到我們的鍵盤錄入的第二種方法(標準輸入流)
package com.westos.Udp02;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
*
* @author 傑哥
*實現發送多條語句
*/
public class SendDome {
public static void main(String[] args) {
try {
//1)創建Socket對象,並且整體給它Try...catch...
DatagramSocket ds=new DatagramSocket();
//2)使用字符串緩衝輸出流錄入數據(鍵盤錄入的第二種方法)
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//一次讀取一行
/**
* 這裏的while循環得把數據報包也包括進去
* 這樣可以每讀取一句話就去往報包裏傳輸一句話知道over結束
*/
String line=null;
while((line=br.readLine())!=null) {
//判斷語句,出現over後就結束輸入數據
if("over".equals(line)) {
break;
}
//創建數據報包
DatagramPacket dp=new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.43.204"),13579);
//發送數據
ds.send(dp);
}
//關閉資源
/**
* 這裏的關閉數據必須得寫在while循環外面
* 不然當你一句話說完後就已經關閉資源了無法再繼續說話
* 就會出現異常:java.net.SocketException: Socket is closed
* 所以我們這裏得注意把它放在while循環的外面
*/
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.westos.Udp02;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDome {
public static void main(String[] args){
try {
//創建Socket類對象
DatagramSocket ds=new DatagramSocket(13579);
/**
* 這裏的while循環是爲了不斷的接收多條數據
*/
//創建數據報包
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys, bys.length);
while(true) {
//接收數據
ds.receive(dp);
//解析數據
String line=new String(dp.getData(),0,dp.getLength());
String ip=dp.getAddress().getHostAddress();
//輸出數據
System.out.println("from"+ip+"Data is"+line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
以上案例是當我們在發送端輸入數據,在接收端接收數據,然後我們還得切換到發送端繼續去輸入數據,那麼有沒有可以在一個控制檯去輸出呢?
分析這裏將運用到我們的多線程問題
package com.westos.Udp03;
import java.io.BufferedReader;import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendDome implements Runnable{
//創建Socket類對象
private DatagramSocket ds;
//創建有參構造
public SendDome (DatagramSocket ds) {
this.ds=ds;
}
@Override
public void run() {
try {
DatagramSocket dsSend=new DatagramSocket();
//創建字符緩衝輸入流對象
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null) {
if("拜拜".equals(line)) {
break;
}
//創建數據報包
DatagramPacket dp=new DatagramPacket
(line.getBytes(), line.getBytes().length,
InetAddress.getByName("192.168.43.204"),10086);
//發生數據報包
ds.send(dp);
}
//關閉數據
dsSend.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.westos.Udp03;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDome implements Runnable{
//創建Socket類對象
private DatagramSocket ds;
//有參構造
public ReceiveDome(DatagramSocket ds) {
this.ds=ds;
}
@Override
public void run() {
try {
//創建數據報包
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys, bys.length);
while(true) {
//去接收它
ds.receive(dp);
//解析數據
String data=new String(dp.getData(),0,dp.getLength());
String ip=dp.getAddress().getHostAddress();
//輸出數據
System.out.println("from"+ip+"data is"+data);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//解析數據
}
}
package com.westos.Udp03;
/**
*我們這裏是爲了創建一個房間可以不斷的去接收數據‘
*所以這裏我們需要運用到多線程 、IO流等
*
*/
import java.io.IOException;
import java.net.DatagramSocket;
public class ChartRoom {
public static void main(String[] args) throws IOException {
//創建發生端對象和接收端對象
DatagramSocket dsSend=new DatagramSocket();
DatagramSocket dsReceive=new DatagramSocket(10086);
//創建資源類對象
SendDome sd=new SendDome(dsSend);
ReceiveDome rd=new ReceiveDome(dsReceive);
//創建Tread類對象
Thread t1=new Thread(sd);
Thread t2=new Thread(rd);
//啓動線程
t1.start();
t2.start();
}
}
Udp編程的原理分析:
1)首先發送端和接收端雙方都必須創建Socket對象
2)發送端設置好自己的ip以及端口號後,接收端也得綁定相對於的端口號
3)將需要發送的數據封裝進數據報包中,在底層通過流的形式發送給接收方,接收端也創建一個數據報包,去接收發送端接收來的數據,然後去解析數據,最終輸出它