我正在编写服务器 - 客户端聊天程序。服务器正确等待传入连接并创建一个线程( IdentThread )来验证用户(询问用户名和密码)。在确认用户身份后, IdentThread 会创建一个 ChatThread 来处理用户输入并将消息发送给其他用户及其关联的客户端。
客户端程序通过缓冲读取器从命令行读取,使用 PrintWriter 将消息发送到服务器,并使用另一个 BufferedReader <接收消息/强>
此模型运作良好。但是,当用户断开连接然后重新连接时,他们会很好地通过 IdentThread ,但在输入 ChatThread 后,服务器或其他用户的所有消息都不可见。我找到的唯一办法就是重新启动服务器程序,这在实际应用中是不可行的。
服务器启动一个新的 IdentThread ,将套接字传递给套接字,让它接受套接字并启动它。
IdentThread 会创建一个新的 BufferedReader 和 PrintWriter 来处理 I / O 。无论客户端多少次连接和断开连接,它们都会一直工作。
通过身份验证后, IdentThread 会创建一个 ChatThread ,并向其传递套接字,用户名,用户ID号,BufferedReader和PrintWriter。
这是我遇到问题的地方。用户连接和断开连接一次后,他们就无法再读取服务器发送给他们的任何消息,尽管他们可以从 IdentThread 中读取消息。用户发送的消息对其他用户可见,服务器正确响应用户发送的命令。
我不确定问题是否是由于我从未有任何绑定到套接字的事实引起的,就像我正在进行通信工作或其他一些我不知道的问题。
编辑:我发布了一些代码,并引入了处理通信的部分。
我觉得问题可能来自我如何将ChatThreads分配给客户
服务器主:
public class Main{
public static boolean listening = false;
public static AtomicInteger connec = new AtomicInteger(0);
public static AtomicInteger onln = new AtomicInteger(0);
public static Hashtable<String, String> passlist = new Hashtable<String, String>();
public static Hashtable<String, Integer> privslist = new Hashtable<String, Integer>();
public static String[] online = new String[20];
public static ChatThread[] clients = new ChatThread[20];
public static void main(String[] args) throws IOException{
ServerSocket listener = null;
int port = 6667;
int backlog = 20;
int maxconnec = 20;
passlist.put("apoc326", "password");
privslist.put("apoc326", 5);
passlist.put("jameson", "password");
privslist.put("jameson", 0);
//create a new server socket
listener = new ServerSocket(port, backlog);
listening = true;
System.out.println("Starting listening to the socket for an incoming connection.");
//if the server is listening for new connections and
//the maximum number of connections hasn't been reached
while(listening == true && connec.get() < maxconnec){
//create a new thread to perform user login and increment number of connections
System.out.println("Listening...");
new IdentThread(listener.accept()).start();
connec.incrementAndGet();
}
//close the server socket
listener.close();
}
}
IdentThread:
public class IdentThread extends Thread{
private Socket mysock = null;
private PrintWriter out = null;
private BufferedReader in = null;
IdentThread(Socket sock){
mysock = sock;
}
public void run(){
try{
out = new PrintWriter(mysock.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(mysock.getInputStream()));
//A whole mess of code removed
if(validName == true && validPass == true){
synchronized(this){
for(int i = 0; i < Main.clients.length; i++){
if(Main.clients[i] == null){
//add the user's name to the list of online users
ID = i;
Main.online[i] = username;
Main.clients[i] = new ChatThread(mysock, username, ID, in, out);
Main.clients[i].start();
Main.onln.incrementAndGet();
ChatThread:
public class ChatThread extends Thread{
private Socket mysock = null;
private PrintWriter out = null;
private BufferedReader in = null;
private boolean online = true;
private String input = null;
private String output = null;
private int ID = -1;
//constructor
ChatThread(Socket sock, String name, int ID, BufferedReader in, PrintWriter out){
mysock = sock;
username= name;
alias = name;
this.in = in;
this.out = out;
this.ID = ID;
privs = Main.privslist.get(username);
}
//executable section of the thread
public void run(){
while(online == true){
try {
input = in.readLine();
}
catch (IOException e) {
e.printStackTrace();
break;
}
output = parse(input);
if(output != null){
sendAll(output);
}
}
try {
in.close();
out.close();
mysock.close();
Main.onln.decrementAndGet();
Main.connec.decrementAndGet();
System.out.println(username + " has disconnected. Online user count: " + Main.onln.get());
System.out.println("ChatThread " + ID + " terminating. Connection count: " + Main.connec.get());
}
catch (IOException e) {
e.printStackTrace();
}
}
客户端:
public class Main {
public static void main(String args[]) throws IOException{
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
String servIP = null;
int port = 6667;
PrintWriter out = null;
BufferedReader in = null;
Socket mysock = null;
boolean connected = false;
String incoming = null;
String outgoing = null;
servIP = console.readLine();
mysock = new Socket(servIP,port);
out = new PrintWriter(mysock.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(mysock.getInputStream()));
connected = true;
while(connected == true){
while(in.ready()){
incoming = in.readLine();
System.out.println(incoming);
}
while(console.ready()){
outgoing = console.readLine();
out.println(outgoing);
if(outgoing.equals("/disco")){
connected = false;
break;
}
}
}
in.close();
out.close();
console.close();
mysock.close();
}