【发布时间】:2020-03-21 12:43:01
【问题描述】:
现在我已经完成了具有服务器和客户端的应用程序,服务器接受客户端请求并将客户端对象添加到 Arraylist 并为每个客户端启动一个新线程。当多个客户端连接时,客户端可以列出所有客户端,并且可以向列表中的任何客户端发送消息。例如client1,client2,client3连接到服务器client1,client2向client3发送消息,会在client3控制台打印。一切正常。现在我需要添加每个客户端在单独聊天中发送消息的附加功能,如果客户端 1 打开与客户端 2 的聊天,则应该只显示这两个客户端之间的对话,而不是客户端 3 消息,反之亦然。要做到这一点,我需要任何额外的概念,比如多线程。我不是在问源代码,我只是在问一个实现上述功能的想法。
谁能告诉我为不同客户端实现单独聊天的建议或参考...需要保留旧消息直到服务器离线?
Server.java
package server;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.*;
import java.util.Vector;
public class Server {
static Vector<ClientHandler> AllClients = new Vector<ClientHandler>();
public static void main(String args[]) throws Exception {
try {
ServerSocket ss = new ServerSocket(1111);
System.out.println("Server Started");
while(true) {
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
String clientname = dis.readUTF();
System.out.println("Connected With : "+clientname);
ClientHandler client = new ClientHandler(s,clientname);
Thread t = new Thread(client);
AllClients.add(client);
t.start();
System.out.println("Ready to accept connections...");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientHandler.java
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientHandler extends Thread{
private DataInputStream in;
private DataOutputStream out;
private String ClientName;
private boolean login;
private Socket Socket;
Scanner sc = new Scanner(System.in);
ClientHandler(Socket s,String name) throws Exception{
this.in = new DataInputStream(s.getInputStream());
this.out = new DataOutputStream(s.getOutputStream());
this.login = true;
this.ClientName = name;
this.Socket = s;
}
public void run() {
while(true) {
try {
String received = in.readUTF();
if(received.equalsIgnoreCase("logout")) {
this.login = false;
this.out.writeUTF("logout");
int i;
for(i = 0; i < Server.AllClients.size(); i++) {
if(this.ClientName.equals(Server.AllClients.get(i).ClientName))
break;
}
Server.AllClients.remove(i);
System.out.println(this.ClientName+" logged out");
this.Socket.close();
break;
}
if(received.equalsIgnoreCase("getlist")) {
for(int i = 0; i < Server.AllClients.size(); i++) {
out.writeUTF(i+1 +", "+Server.AllClients.get(i).ClientName);
}
continue;
}
if(received.contains(",")) {
String[] Message = received.split(",");
for(ClientHandler c : Server.AllClients) {
if(c.ClientName.equalsIgnoreCase(Message[1]) && c.login) {
c.out.writeUTF(this.ClientName +" : "+ Message[0]);
c.out.flush();
break;
}
}
}
}catch(Exception e) {
System.out.println("Error :"+e.getMessage());
}
}
try {
this.in.close();
this.out.close();
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
Client.java
package client;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client {
static DataInputStream dis;
static DataOutputStream dos;
static Socket s;
public static void main(String args[])throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("Enter Cient Name : ");
String name = sc.nextLine();
s = new Socket("localhost",1111);
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(name);
Thread sendMessage = new Thread(new Runnable()
{
@Override
public void run() {
while (true) {
String msg = sc.nextLine();
try {
dos.writeUTF(msg);
if(msg.equalsIgnoreCase("logout")) {
System.out.println("Logged out");
break;
}
} catch (IOException e) {
System.out.println("Error in send method :"+e.toString());
}
}
}
});
Thread readMessage = new Thread(new Runnable()
{
@Override
public void run() {
while (true) {
try {
String msg = dis.readUTF();
if(msg.equalsIgnoreCase("logout")) {
System.out.println("Logged out");
break;
}
System.out.println(msg);
} catch (IOException e) {
System.out.println("Error in read method :"+e.getMessage());
}
}
}
});
sendMessage.start();
readMessage.start();
}
}
如果我的代码有任何不相关的陈述,请提出更好的优化代码的方法
【问题讨论】:
标签: java sockets tcp client-server serversocket