UDP實現聊天
我們知道UDP無需建立連接就可發送信息,就像QQ一樣,無論對方是否在線,你都可以發送消息。下面用UDP來實現聊天功能。
單線程發送接收數據
發送方發送數據
接收方接收數據
發送方代碼
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class Demo01Sender {
public static void main(String[] args) throws Exception {
//1.建立一個socket,參數是自己的端口號
DatagramSocket socket = new DatagramSocket(8888);
//準備數據,控制檯讀取輸入
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String data = reader.readLine();
byte[] datas = data.getBytes();
//2.創建數據包
//參數:數據,數據開始點,數據長度,發送的地址
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
//3.發送數據包
socket.send(packet);
if (data.equals("bye")){
break;
}
}
socket.close();
}
}
接收方代碼
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Demo01Receiver {
public static void main(String[] args) throws Exception {
//1.創建socket
DatagramSocket socket = new DatagramSocket(6666);
while (true) {
//2.準備接收包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.阻塞式接受包裹
socket.receive(packet);
//顯示接受數據
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(receiveData);
if (receiveData.equals("bye")){
break;
}
}
socket.close();
}
}
多線程實現雙方互相發送數據
上述代碼只能實現單方發送與接收,而要實現雙方互相發送數據和接收數據則要用到多線程。
佐伊
伊澤瑞爾
首先編寫發送和接收的Runnable實現類
發送
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 TalkSend implements Runnable{
DatagramSocket socket = null;
BufferedReader reader = null;
private int fromPort;
private String toIP;
private int toPort;
public TalkSend(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
}
@Override
public void run() {
//1.建立一個socket,參數是自己的端口號
try {
socket = new DatagramSocket(fromPort);
//準備數據,控制檯讀取輸入
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
try {
String data = reader.readLine();
byte[] datas = data.getBytes();
//2.創建數據包
//參數:數據,數據開始點,數據長度,發送的地址
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(toIP, toPort));
//3.發送數據包
socket.send(packet);
if (data.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
接收
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TalkReceive implements Runnable{
DatagramSocket socket=null;
private int port;
private String msgFrom;
public TalkReceive(int port ,String msgFrom) {
this.port = port;
this.msgFrom = msgFrom;
}
@Override
public void run() {
//1.創建socket
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
try {
//2.準備接收包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.阻塞式接受包裹
socket.receive(packet);
//顯示接受數據
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(msgFrom+":"+receiveData);
if (receiveData.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
雙方線程創建啓動
佐伊
public class TalkZoe {
public static void main(String[] args) {
new Thread(new TalkSend(2222,"localhost",8888)).start();
new Thread(new TalkReceive(6666,"伊澤瑞爾")).start();
}
}
伊澤瑞爾
public class TalkEz {
public static void main(String[] args) {
new Thread(new TalkSend(3333,"localhost",6666)).start();
new Thread(new TalkReceive(8888,"佐伊")).start();
}
}