这篇文章我们利用网络编程和多线程的知识来解决该问题,旨在如果我们在一个群中一个客户端发送信息,该群中的所有客户端都会看见。
1.服务端
package webCoding;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
//向三个客户端发送消息时,先将发送消息的线程处于等待状态,将公共数据区的数据发送给客户端
public class ChatRoomServer {
//定义公共数据区
public static String buf;
public static void main(String[] args) {
System.out.println("Chat Server Version 1.0");
System.out.println("Listen at 8888.....");
try(ServerSocket serverSocket = new ServerSocket(7777))
{
while(true)
{
Socket socket = serverSocket.accept();
System.out.println("连接到"+socket.getInetAddress());
new ChatReceive(socket).start();
new ChatSend(socket).start();
}
//程序循环监听端口,多个客户端可以连接服务端。
}catch (Exception e){
System.out.println("连接失败..........");
}
}
}
//接收客户端消息的线程类
class ChatReceive extends Thread{
private Socket socket;
public ChatReceive(Socket socket)
{
this.socket = socket;
}
public void run()
{
this.receiveMsg();
}
//实现接收客户端发来的信息
private void receiveMsg() {
try(BufferedReader br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()))){
while(true){
String msg = br.readLine();
synchronized ("abc"){
//把读取到的数据写入公共数据区
ChatRoomServer.buf="["+this.socket.getInetAddress()+"] "+msg;
//唤醒发送消息的线程对象。
"abc".notifyAll();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
//向客户端发送消息的线程类
class ChatSend extends Thread{
private Socket socket;
public ChatSend(Socket socket){
this.socket = socket;
}
@Override
public void run() {
this.sendMsg();
}
private void sendMsg(){
try(PrintWriter printWriter = new PrintWriter(socket.getOutputStream()))
{
while(true)
{
synchronized ("abc"){
//让发送消息的线程处于等待状态
"abc".wait();
//将公共数据区中的消息发送给客户端
printWriter.println(ChatRoomServer.buf);
printWriter.flush();
}
}
}catch (Exception e)
{
System.out.println("发送失败....");
}
}
}
2.客户端
package webCoding;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;
import java.util.Scanner;
public class GoodTCP {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入: server,<port> 或者:<ip>,<port>");
String str = scanner.nextLine();
String [] temp = str.split(",");
if (Objects.equals("server",temp[0]))
{
System.out.println("TCP Server Listen at "+temp[1]+" .....");
serverSocket = new ServerSocket(Integer.parseInt(temp[1]));
socket = serverSocket.accept();//监听端口
System.out.println("连接成功");
}
else {
System.out.println("TCP Server Listen at "+temp[0]+","+temp[1]);
socket = new Socket(temp[0],Integer.parseInt(temp[1]));
System.out.println("连接成功");
}
new send(socket).start();
new Receives(socket).start();
}catch (Exception e)
{
System.out.println("连接失败......");
}finally{
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class send extends Thread{
private Socket socket;
public send(Socket socket)
{
this.socket = socket;
}
public void run()
{
this.sendMsg();
}
//发送消息线程
private void sendMsg() {
try(Scanner scanner = new Scanner(System.in);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream())){
while(true)
{
String tmp = scanner.nextLine();
printWriter.println(tmp);
printWriter.flush();
if (Objects.equals("exit",tmp))
{
System.out.println("结束聊天");
break;
}
}
}catch (Exception e)
{
System.out.println("发送失败");
}
}
}
class Receives extends Thread
{
private Socket socket;
public Receives(Socket socket)
{
this.socket = socket;
}
public void run()
{
this.receiveMsg();
}
//接收消息线程
private void receiveMsg() {
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())))
{
while (true)
{
String temp = bufferedReader.readLine();
System.out.println("服务端:"+temp);
if (Objects.equals("exit",temp))
{
System.out.println("对方已结束聊天");
break;
}
}
}catch (Exception e)
{
System.out.println("接受失败.....");
}
}
}
3.运行结果
4.运行过程
在这个程序中,两个线程的运行顺序是交替的,因为它们都是独立的线程并且都在运行。具体的运行顺序取决于操作系统的调度机制,但是一般情况下可以这样描述:
1.当程序启动时,创建一个ChatReceive线程和一个ChatSend线程,并启动它们。
2.ChatReceive线程开始运行,调用receiveMsg方法来接收客户端发送的消息。
3.ChatSend线程开始运行,调用sendMsg方法来发送消息。由于"abc".wait()的存在,它会进入等待状态。
4.当ChatReceive线程接收到消息时,它会将消息写入公共数据区ChatRoomServer.buf,并唤醒ChatSend线程。
5.ChatSend线程被唤醒后,它会从公共数据区中获取消息,并发送给客户端。
6.ChatSend线程发送完消息后,再次进入等待状态。
重复步骤4-6,实现接收和发送消息的交替运行。
总的来说,这两个线程的运行顺序是交替的,一个线程接收消息,另一个线程发送消息,通过共享的公共数据区来实现线程间的通信。
宝贝们,喜欢的话就点个赞吧!