你可以帮助我使用这段代码,因为我尝试使用If语句但是没有用。我并没有要求为我写代码只是指着我。
主要的问题是,每次有人连接时,都会制作新的线程但是当他关闭聊天框时,脚踏板会保持打开并且不能正常工作。我的意思是有些人自己建立了10个连接,没有其他人可以聊天。
import java.net.*;
import java.io.*;
public class myServer {
static ServerSocket server;
static Socket client;
static DataInputStream in;
static DataOutputStream out;
static clientThread t[] = new clientThread[10];
public static void main(String[] args) throws IOException {
System.out.println("Starting Server");
server = new ServerSocket(7555);
System.out.println("Started Server");
while (true) {
client = server.accept();
System.out.println("CONNECTION");
out = new DataOutputStream(client.getOutputStream());
out.writeUTF("Welcome to the chat room");
for (int i = 0; i <= 9; i++) {
if (t[i] == null) {
(t[i] = new clientThread(client, t)).start();
break;
}
}
}
}
}
class clientThread extends Thread {
DataInputStream in;
DataOutputStream out;
static String msg;
Socket client = null;
clientThread t[];
public clientThread(Socket client, clientThread[] t) {
this.client = client;
this.t = t;
}
public void run() {
try {
in = new DataInputStream(client.getInputStream());
out = new DataOutputStream(client.getOutputStream());
boolean tru = true;
while (tru) {
msg = in.readUTF();
System.out.println(msg);
for (int i = 0; i <= 9; i++)
if (t[i] != null) {
t[i].out.writeUTF(msg);
System.out.println(t[i]);
}
}
} catch (IOException e) {
}
}
}
答案 0 :(得分:1)
您的问题不在于线程保持打开,而是您没有将客户端线程标记为已完成的机制。即使线程已退出,t[i]
也不会成为null
。它仍然会引用一个线程的实例 - 只是一个“死”线程。
以下是两种解决方法:
在线程退出之前,标记t[i] = null
(其中i
是当前线程的索引)。请注意,您需要在每个帖子中存储i
的值。
clientThread
并添加private int threadIndex;
作为成员变量。修改clientThread
的构造函数并添加threadIndex
作为参数。
public clientThread(Socket client, clientThread[] t, int threadIndex)
{
this.threadIndex=threadIndex;
//...
}
在run
的右大括号之前,添加
synchronized(t){t[this.threadIndex]=null;}
使用Executor
并将clientThread
提交给它。 Java的Executor
将为您处理清理线程。
答案 1 :(得分:1)
为什么只为一个套接字连接创建10个线程?我想你想要为每个到聊天服务器的传入连接创建一个ClientThread。然后将该单个ClientThread添加到活动聊天列表中。当聊天客户端终止会话时,从该列表中删除该条目。您不需要将Thread实例或ClientThreads数组传递给ClientThread的构造函数,因为它本身就是这样。只需将Socket实例传递给ClientThread,并引用ChatServer即可。如果您正在尝试创建聊天室。然后允许服务器处理向其他人发送消息:
public class ChatServer {
List<ClientThread> activeParticipants;
public void say( ClientThread author, String message ) {
for( ClientThread current : activeParticipants ) {
if( current != author ) {
current.send( message ); // this method will send a message to that client
}
}
}
}
您需要使用两个线程,或使用InputStream.available()方法检查是否某些输入位于System.in或套接字的输入流中。这将允许您读取进入的消息以及允许用户同时键入消息。阻塞read()方法意味着在输入某些数据或接收数据之前,您无法看到消息。
同时将欢迎消息移动到ClientThread中,这样就不会使用两个不同的DataOutputStreams调用Socket.getOutputStream()两次。
答案 2 :(得分:0)
两次调用方法client.getOutputStream(),每次构建一个DataOutputStream。尝试直接在ClientThread中欢迎用户。