聊天室的实现(多线程)
服务器端
思路:服务器提供ServerSocket 配置好端口号 8088
serverSocket.accept 进行侦察有没有客户端进行连接 同时还需要进行已经接受到的客户端的信息交换的功能
故需要开辟一个服务器的子线程进行数据的交换 同时 serverSocket.accept 在主线程中进行侦察连接
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("--------服务器启动-------");
ServerSocket server = new ServerSocket(8088); //设置好服务器连接的端口号
Vector<Socket> sockets = new Vector<>();
//由于有多个客户端进行连接,同时考虑线程安全的问题 故采用Vector 把获得的socket进行存储
while (true) {
Socket socket = server.accept(); //主线程进行 socket连接的监听
sockets.add( socket ); //将得到的socket存入集合
//因为最后要把消息全部发给每一个socket
//开辟子线程 - 负责信息转发 在转发消息的同时也能进行socket监听
ServerThread serverThread = new ServerThread( socket,sockets );
serverThread.start();
}
}
}
服务器的子线程
在主线程监听socket连接的同时还能进行 消息的转发
public class ServerThread extends Thread {
private Socket socket;
private Vector<Socket> sockets;
public ServerThread(Socket socket, Vector<Socket> sockets) {
this.socket = socket;
this.sockets = sockets;
}
public void run(){
while (true){
//接收消息
BufferedReader br = null;
String ip = null;
try {
ip = socket.getInetAddress().getHostAddress();
br = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
String msg = "";
while ((msg=br.readLine())!=null){
System.out.println(ip+": "+msg);
//收到消息后 并把消息发给所有的socket
sendMessage( ip+": "+msg );
}
} catch (IOException e) {
System.out.println(ip+":断开连接");
}
}
}
public void sendMessage(String msg){
PrintStream printStream = null;
try {
for (Socket socket :sockets){
printStream = new PrintStream( socket.getOutputStream() );
printStream.println( msg );
printStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
通过服务器的IP地址和ServerSocket开辟的端口号进行对服务器的访问
多线程的同时对 接收消息进行 多线程的分配 使得客户端可以同时的 接受 和 发送 消息4
public class Client {
public static void main(String[] args) {
System.out.println("----谭佳龙----");
try {
Socket socket = new Socket("192.168.31.214",8088);
//发送信息
SendThread sendThread = new SendThread( socket );
sendThread.start();
//接受信息
ReciverThread reciverThread = new ReciverThread(socket);
reciverThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ReciverThread
public class ReciverThread extends Thread {
private Socket socket;
public ReciverThread(Socket socket) {
this.socket = socket;
}
public void run(){
BufferedReader br = null;
while (true){
try {
br = new BufferedReader(new InputStreamReader( socket.getInputStream() ));
String msg = "";
while ((msg=br.readLine())!=null){
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
SendThread
public class SendThread extends Thread {
private Socket socket;
public SendThread(Socket socket) {
this.socket = socket;
}
public void run(){
while (true){
Scanner input = new Scanner( System.in );
String msg = input.nextLine();
try {
PrintStream pw = new PrintStream( socket.getOutputStream() );
pw.println( msg );
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
引入了Thread 线程
可以一边发送和接受
由于有多个客户端进行连接,同时考虑线程安全的问题 故采用Vector 把获得的socket进行存储
开辟子线程 - 负责信息转发 在转发消息的同时也能进行socket监听