java實現聊天,服務端與客戶端程式碼(UDP)-狂神改
阿新 • • 發佈:2022-03-30
首先是檔案結構:
最後run的是下面兩個
程式碼用的狂神的,不過他寫的有點小bug,比如傳資訊會出現一堆空格(recieve data那裡長度不應該用data.lenth()而應該用packet.getLenth()),
以及你輸入退出關鍵詞後,會同時把兩邊都close掉,雖然好像也可以這樣不過怪怪的,於是我分開了
在這裡用/exit作為退出關鍵詞。輸入後,輸入方直接exit(0),接收方此時會收到“對方已下線”的提醒,這時候也可以輸入/exit退出。
ok接下來是程式碼:
1.TalkRecieve
package socket.chat; import java.io.IOException;import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; import static java.lang.System.exit; public class TalkRecieve implements Runnable{ DatagramSocket socket = null; private int port; private String msgFrom; public TalkRecieve(int port,String msgFrom) {this.port = port; this.msgFrom = msgFrom; try { socket = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while(true){ try{ byte[] container = newbyte[1024]; DatagramPacket packet = new DatagramPacket(container,0,container.length); socket.receive(packet);//等待接受包裹 //斷開連線 byte[] data = packet.getData(); String receiveData = new String(data,0,packet.getLength()); System.out.println(msgFrom+":"+receiveData); if(receiveData.equals("/exit")){ System.out.println("【系統】:對方已下線。使用/exit退出"); break; } }catch (IOException e){ e.printStackTrace(); } } socket.close(); } }
2.TalkSend
package socket.chat; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import static java.lang.System.exit; 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; try{ socket = new DatagramSocket(fromPort); reader = new BufferedReader((new InputStreamReader(System.in))); }catch(Exception e){ e.printStackTrace(); } } @Override public void run() { //準備資料,控制檯讀取 while(true){ try{ String data = reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort)); socket.send(packet); if(data.equals("/exit")) { break; } }catch(Exception e){ e.printStackTrace(); } } socket.close(); exit(0); } }
3.TalkStudent(一方)
package socket.chat; //學生從7777發出,發向對方的9999 //學生準備從8888接收老師的訊息 //從哪裡發出並不重要,重要的是發向哪裡和接收在哪裡 public class TalkStudent { public static void main(String[] args) { new Thread(new TalkSend(7777,"localhost",9999)).start(); new Thread(new TalkRecieve(8888,"老師")).start(); } }
4.TalkTeacher(另一方)
基本一致,只是send的port和reiceve的prot換了
這裡傳送來源port是無所謂的(只要別填個會被佔用的就行了)
package socket.chat; //學生從7777發出,發向對方的9999 //學生準備從8888接收老師的訊息 //從哪裡發出並不重要,重要的是發向哪裡和接收在哪裡 public class TalkStudent { public static void main(String[] args) { new Thread(new TalkSend(7777,"localhost",9999)).start(); new Thread(new TalkRecieve(8888,"老師")).start(); } }