UDP通信需要明確的幾點: (1).只不過對於發送端來說,創建發送報文對象需要指定目標套接字信息(ip+port),還需明確數據發送緩衝區。 (2).而對於接收端來說,則只需明確一個數據接收緩衝區即可。 UDPSender端: UDPRecver端: UDP實現群聊: 思路: 註:若您覺得這篇文章還 ...
UDP通信需要明確的幾點:
- UDP通信不是面向連接的,發送端不管接收端是否啟動是否能接收,發完數據報就結束。
- 無論是發送端還是接收端,都需要描述兩個對象:套接字和數據報。
- 接收端的套接字對象中必須明確接收埠,且必須和發送端指定的目標埠一致。而發送端的套接字中則一般採用隨機分配的發送埠。
- 無論是發送端還是接收端,數據報中都記錄了自己和對方的socket信息(ip+port),還提供了用於發送或接收的數據緩衝區。這些數據只有數據報對象自己最清楚,如
getPort()
,getAddress()
,getData()
等。- (1).只不過對於發送端來說,創建發送報文對象需要指定目標套接字信息(ip+port),還需明確數據發送緩衝區。
- (2).而對於接收端來說,則只需明確一個數據接收緩衝區即可。
- 接收端應該不斷迴圈地負責接收。
- UDP套接字類DatagramSocket,UDP數據報類DatagramPacket。
UDPSender端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UDPSender {
public static void main(String[] args) {
DatagramSocket dgs = null;
try {
// 1. 創建udp發送端的socket,一般使用隨機發送埠
dgs = new DatagramSocket();
// 2. 創建udp報文包對象
// 2.1 創建數據發送緩衝區
String text = "Hello World! I'm coming";
byte[] buf = text.getBytes();
// 2.2 創建發送數據報文對象
InetSocketAddress isa = new InetSocketAddress("192.168.0.124",8888);
DatagramPacket dgp = new DatagramPacket(buf,buf.length,isa);
//DatagramPacket dgp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.0.124"), 8888);
// 3.發送udp報文
dgs.send(dgp);
} catch (SocketException e1) {
e1.printStackTrace();
} catch (UnknownHostException e2) {
e2.printStackTrace();
} catch (IOException e3) {
e3.printStackTrace();
} finally {
// 4. 關閉套接字
dgs.close();
}
}
}
UDPRecver端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UDPRecver {
public static void main(String[] args) {
while(true){
// 1.創建udp接收套接字,接收端必須指定正確的埠
DatagramSocket dgs = null;
try {
dgs = new DatagramSocket(8888);
// 2. 創建udp接收數據包對象
byte[] buf = new byte[1024];
DatagramPacket dgp = new DatagramPacket(buf, buf.length);
// 3.從套接字中接收數據到數據包中
dgs.receive(dgp);
// 4.展示udp發送端相關信息,包括發送的數據
String data = new String(dgp.getData(), 0, dgp.getLength());
String ip = dgp.getAddress().getHostAddress();
int port = dgp.getPort();
System.out.println("Data: "+data+" ip: "+ip+" port: "+port);
} catch (SocketException s) {
s.printStackTrace();
} catch (IOException i) {
i.printStackTrace();
} finally {
dgs.close();
}
}
}
}
UDP實現群聊:
思路:
- 一個線程負責發,一個線程負責收,因此使用多線程。
- 發送端的數據報目標端應該指定為廣播目標。且發送的數據來源於鍵盤輸入。
- 接收端要無限迴圈接收數據,但應該提供下線離開功能。(假設收到了"bye",就表示下線)
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class QunChat {
public static void main(String[] args) throws SocketException {
//發送端和接收端套接字,接收端套接字埠為8888,需要傳遞給發送端的報文對象
DatagramSocket send_socket = new DatagramSocket();
DatagramSocket recv_socket = new DatagramSocket(8888);
Sender sender = new Sender(send_socket,8888);
Recver recver = new Recver(recv_socket);
Thread send_thread1 = new Thread(sender);
Thread recv_thread1 = new Thread(recver);
send_thread1.start();
recv_thread1.start();
}
}
class Sender implements Runnable {
private DatagramSocket send_sock;
private int dest_port;
Sender(DatagramSocket s,int port){ //初始化時就指定目標埠
this.send_sock = s;
this.dest_port = port;
}
public void run() {
while(true) {
try {
//群聊發送目標,以廣播為例
InetSocketAddress isa = new InetSocketAddress("192.168.0.255", dest_port);
//從鍵盤接收數據
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line=bufr.readLine())!=null) {
//如果發送的是bye,則斷開,且不發送給接收端
if(line.equals("bye")) break;
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length, isa);
send_sock.send(dp);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
send_sock.close();
}
}
}
}
class Recver implements Runnable {
private DatagramSocket recv_sock;
Recver(DatagramSocket socket){
this.recv_sock = socket;
}
public void run() {
while(true) {
try {
//接收報文對象
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
recv_sock.receive(dp);
String src_ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
if(data.equals("bye")) System.out.println(src_ip +" leaving");;
System.out.println("Recviving data: "+ data+" from "+src_ip );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!