在java網路程式設計中實現伺服器和客戶端一對一的聊天
阿新 • • 發佈:2019-02-14
如果有多個客戶端接入,都可以傳送訊息給伺服器,但伺服器只和最後一個客戶聊天。,如果要實現群聊的話,只要把所有的socket儲存到集合中,有客戶輸入時遍歷socket得到輸出流並把訊息廣播給各個客戶端就行了。
四個讀寫的執行緒類都是一樣的,可以進行封裝,這裡就不封裝了。
Server伺服器主程式
package server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { private ServerSocket serversocket; //構造方法 public Server() { try { // 得到伺服器套接字 serversocket = new ServerSocket(8888); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void start() { try { while (true) { // 等待客戶端接入,並通過 套接字得到socket Socket socket = serversocket.accept(); System.out.println("有客戶接入了"); new Thread(new ServerReaderThread(socket)).start(); new Thread(new ServerWriterThread(socket)).start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { Server server = new Server(); server.start(); } }
伺服器專門用來讀使用者資料的執行緒類
ServerReaderThread
package server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; public class ServerReaderThread implements Runnable{ private Socket socket; private BufferedReader bf; private PrintWriter pw; public ServerReaderThread(Socket socket){ this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub // 得到輸入和輸出流 InputStream is; try { is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); // 包裝流 bf = new BufferedReader(new InputStreamReader(is)); pw = new PrintWriter(os); //迴圈讀取客戶端輸入的資料 while(true){ //讀取一行資料 String info = bf.readLine(); System.out.println(info); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
伺服器專門用來發送資料給客戶的執行緒類
ServerWriterThread
package server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; public class ServerWriterThread implements Runnable{ private Socket socket; private BufferedReader bf; private PrintWriter pw; public ServerWriterThread(Socket socket){ this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub // 得到輸入和輸出流 InputStream is; try { is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); // 包裝流 bf = new BufferedReader(new InputStreamReader(is)); pw = new PrintWriter(os); Scanner sc = new Scanner(System.in); //迴圈讀取伺服器輸入的資料併發送給客戶端 while(true){ //讀取一行資料 String info = sc.nextLine(); pw.println(info); pw.flush(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Client 客戶端主程式
package client;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Client {
private Socket socket;
// 構造方法
public Client() {
try {
// 得到連線到伺服器的socket
socket = new Socket("localhost", 8888);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
// 等待客戶端接入,並通過 套接字得到socket
new Thread(new ClientReaderThread(socket)).start();
new Thread(new ClientWriterThread(socket)).start();
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
客戶端用來讀取資料的執行緒類
ClientReaderThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientReaderThread implements Runnable {
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ClientReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到輸入和輸出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包裝流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
// 迴圈讀取客戶端輸入的資料
while (true) {
// 讀取一行資料
String info = bf.readLine();
System.out.println(info);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客戶端用來發送訊息的執行緒類
ClientWriterThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientWriterThread implements Runnable {
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ClientWriterThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到輸入和輸出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包裝流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
Scanner sc = new Scanner(System.in);
// 迴圈讀取伺服器輸入的資料併發送給客戶端
while (true) {
// 讀取一行資料
String info = sc.nextLine();
pw.println(info);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}