JAVA_網路程式設計_TCP_Socket通訊_聊天室_多人聊天/私聊_實現
阿新 • • 發佈:2018-12-26
Socket程式設計 連線(連線是通過輸入輸出流來傳送資料)
建立伺服器
package com.hp.tcp; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; /** * 服務端 * * @author 曉電腦 */ public class Service { //建立一個容器用於接受每一個連線 private List<ServiceThread> serviceThreadList=new ArrayList<>(); public static void main(String[] args) throws IOException { new Service().connect(); } public void connect() throws IOException { //建立伺服器 指定埠 ServerSocket socket = new ServerSocket(8888); while (true) { Socket accept = socket.accept(); ServiceThread thread = new ServiceThread(accept); serviceThreadList.add(thread); new Thread(thread).start(); } } class ServiceThread implements Runnable { private DataInputStream stream; private DataOutputStream outputStream; private boolean isRuning = true; private String name; public ServiceThread() { } public ServiceThread(Socket socket) { try { //接受客戶端的資料的流 stream = new DataInputStream(socket.getInputStream()); //返回客戶端資料的流 outputStream = new DataOutputStream(socket.getOutputStream()); this.name = stream.readUTF(); send("歡迎進入聊天室"); sendOthers(name+"進入了聊天室",false); } catch (IOException e) { // e.printStackTrace(); CloseUtils.close(stream, outputStream); isRuning = false; serviceThreadList.remove(this); } } /** * 接受客戶端資料 * * @return */ public String accept() { String readUTF = null; try { readUTF = stream.readUTF(); } catch (IOException e) { // e.printStackTrace(); CloseUtils.close(stream); isRuning = false; serviceThreadList.remove(this); } return readUTF; } /** * 傳送客戶端資料 */ public void send(String acept) { try { outputStream.writeUTF(acept); outputStream.flush(); } catch (IOException e) { // e.printStackTrace(); CloseUtils.close(stream); isRuning = false; serviceThreadList.remove(this); } } /** * 發給其他客戶端 */ public void sendOthers(String accept,boolean flag){ //私聊的實現 if (accept.startsWith("@") && accept.indexOf(":")>-1){ String title=accept.substring(1,accept.indexOf(":")); String content=accept.substring(accept.indexOf(":")+1); for (ServiceThread serviceThread : serviceThreadList) { if (serviceThread.name.equals(title)){ serviceThread.send(this.name+"對你私聊說"+content); } } }else { for (ServiceThread serviceThread : serviceThreadList) { if (serviceThread.equals(this))continue; if (flag){ serviceThread.send(this.name+"對所有人說"+accept); }else { serviceThread.send("系統訊息"+accept); } } } } @Override public void run() { while (isRuning){ sendOthers(accept(),true); } } } }
建立客戶端
package com.hp.tcp; import java.io.*; import java.net.Socket; /**客戶端 * @author 曉電腦 */ public class Client { public static void main (String[] args) throws IOException { System.out.println("請輸入名稱"); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String readLine = reader.readLine(); if (readLine == null){ return; } //建立客戶端 指定伺服器 Socket socket = new Socket("localhost",8888); new Thread(new Send(socket,readLine)).start(); new Thread(new Accept(socket)).start(); } }
建立傳送資訊的執行緒
package com.hp.tcp; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /**傳送訊息執行緒 * @author 曉電腦 */ public class Send implements Runnable { private BufferedReader bufferedReader; private DataOutputStream dataOutputStream; private boolean isRun=true; //名稱 private String name; public Send(){ bufferedReader=new BufferedReader(new InputStreamReader(System.in)); } public Send(Socket socket,String name){ this(); try { dataOutputStream = new DataOutputStream(socket.getOutputStream()); this.name=name; send(name); } catch (IOException e) { //e.printStackTrace(); isRun=false; CloseUtils.close(dataOutputStream,bufferedReader); } } /** * 接受伺服器資料 * @return */ public String accept(){ String readLine=null; try { readLine = bufferedReader.readLine(); } catch (IOException e) { //e.printStackTrace(); isRun=false; CloseUtils.close(dataOutputStream,bufferedReader); } return readLine; } /** * 發給伺服器資料 * @param str */ public void send(String str){ try { dataOutputStream.writeUTF(str); } catch (IOException e) { // e.printStackTrace(); isRun=false; CloseUtils.close(dataOutputStream,bufferedReader); } } @Override public void run() { while (isRun){ send(accept()); } } }
接受訊息執行緒
package com.hp.tcp;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接受的執行緒
*/
public class Accept implements Runnable {
private DataInputStream dataInputStream;
private boolean isRun=true;
public Accept(){}
public Accept(Socket socket){
try {
this.dataInputStream=new DataInputStream(socket.getInputStream());
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(dataInputStream);
isRun=false;
}
}
public void write(){
String str=null;
try {
str=dataInputStream.readUTF();
System.out.println(str);
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(dataInputStream);
isRun=false;
}
}
@Override
public void run() {
while (isRun){
write();
}
}
}
群聊執行效果為
在另一個客戶端可以接受到
私聊功能的效果
在qwe客戶端可以接受到
在另一個客戶端是接收不到私聊資料的