在 java 套接字编程中管理所有传入的聊天消息
Manage all incoming chat messages in java socket programming
我正在开发一个具有聊天功能的程序,并且在其中使用套接字。
就我而言,我想在不同的 window 聊天中处理每个客户端(请查看附加图像)。
目前1个客户端连接时,没有问题。但是当连接 2 个客户端时,第一个客户端将被第二个客户端覆盖,除非我关闭最新连接的客户端的连接,否则他无法从服务器接收消息(服务器仍在接收来自所有客户端的消息,尽管只有一个客户端可以从服务器接收)。
我该怎么做?我正在使用 captain casa 框架
我想像下图那样管理它。
IMAGE HERE
这是我的代码:
服务器:
public void mainserver(){
Thread server = new Thread(new Runnable() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
System.out.println("Server Online... \nWaiting for Connections");
} catch (IOException e) {
e.printStackTrace();
}
while (accept){
try {
socket = serverSocket.accept();
System.out.println("New Connection Estasblished!!!");
chatHandler chat = new chatHandler(socket);
chat.start();
} catch (IOException e) {
System.out.println("server not terminate all connections");
System.exit(-1);
}
}
}
});
server.start();
}
public class chatHandler extends Thread{
Socket socket;
public chatHandler(Socket socket){
this.socket = socket;
}
public void run(){
try {
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
dout.writeUTF("Hi! Thank you for reaching us! How may I help you!?");
while (!read.equals(".end")){
read = din.readUTF();
if (getServerArea()!=null){
setServerArea(getServerArea()+"\n"+read);
}else {
setServerArea(read);
}
}
System.out.println("end of chat server");
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("Exit");
try {
dout.close();
din.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void serverSend(javax.faces.event.ActionEvent event) { // "Send" button
write = getServerField();
try {
dout.writeUTF(write);
dout.flush();
if (getServerArea()!=null){
setServerArea(getServerArea()+"\n"+write);
setServerField("");
}else {
setServerArea(write);
setServerField("");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(write);
}
客户:
public void client(){
Thread client = new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket("localhost",port);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
while (!read.equals("bye")){
read = din.readUTF();
if (getClientArea()!=null){
setClientArea(getClientArea()+"\n"+read);
}else {
setClientArea(read);
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
din.close();
dout.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
client.start();
}
public void clientSend(javax.faces.event.ActionEvent event) {
write = getClientField();
try {
dout.writeUTF(write);
dout.flush();
if (getClientArea()!=null){
setClientArea(getClientArea()+"\n"+write);
setClientField("");
}else {
setClientArea(write);
setClientField("");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(write);
}
我相信我理解这个问题,以及如何纠正它。
您正在为每个新连接使用唯一的线程 (chatHandler)。
该线程在连接时自动写入 "Hello",但此后专门用于读取消息(在 while 循环中您只读取 din)并相应地更新控制台。由于每个线程都在管理对 din 的引用,因此所有传入的消息都是正常的。
但是,回写到客户端(serverSend)似乎不是在一个线程中;它由按钮事件触发。此时,dout 将是对最近连接的引用,而不是对打算获取消息的客户端的引用。这就是最近的客户端收到所有未来消息的原因。
更正是为目标客户选择正确的'dout'。当服务器 'operator' 选择回写消息(单击发送按钮)时,您需要以某种方式为该客户端获取正确的 'dout'。
一种方法是在创建线程之前建立 dout(使用套接字),并维护每个客户端之间的关系,以及它对应的 dout(即在 Map 中)。
如果问题仍然不清楚(每个客户必须对 dout 有唯一的引用),请告诉我,我会尽力澄清。
我正在开发一个具有聊天功能的程序,并且在其中使用套接字。 就我而言,我想在不同的 window 聊天中处理每个客户端(请查看附加图像)。
目前1个客户端连接时,没有问题。但是当连接 2 个客户端时,第一个客户端将被第二个客户端覆盖,除非我关闭最新连接的客户端的连接,否则他无法从服务器接收消息(服务器仍在接收来自所有客户端的消息,尽管只有一个客户端可以从服务器接收)。
我该怎么做?我正在使用 captain casa 框架 我想像下图那样管理它。
IMAGE HERE
这是我的代码: 服务器:
public void mainserver(){
Thread server = new Thread(new Runnable() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
System.out.println("Server Online... \nWaiting for Connections");
} catch (IOException e) {
e.printStackTrace();
}
while (accept){
try {
socket = serverSocket.accept();
System.out.println("New Connection Estasblished!!!");
chatHandler chat = new chatHandler(socket);
chat.start();
} catch (IOException e) {
System.out.println("server not terminate all connections");
System.exit(-1);
}
}
}
});
server.start();
}
public class chatHandler extends Thread{
Socket socket;
public chatHandler(Socket socket){
this.socket = socket;
}
public void run(){
try {
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
dout.writeUTF("Hi! Thank you for reaching us! How may I help you!?");
while (!read.equals(".end")){
read = din.readUTF();
if (getServerArea()!=null){
setServerArea(getServerArea()+"\n"+read);
}else {
setServerArea(read);
}
}
System.out.println("end of chat server");
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("Exit");
try {
dout.close();
din.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void serverSend(javax.faces.event.ActionEvent event) { // "Send" button
write = getServerField();
try {
dout.writeUTF(write);
dout.flush();
if (getServerArea()!=null){
setServerArea(getServerArea()+"\n"+write);
setServerField("");
}else {
setServerArea(write);
setServerField("");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(write);
}
客户:
public void client(){
Thread client = new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket("localhost",port);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
while (!read.equals("bye")){
read = din.readUTF();
if (getClientArea()!=null){
setClientArea(getClientArea()+"\n"+read);
}else {
setClientArea(read);
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
din.close();
dout.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
client.start();
}
public void clientSend(javax.faces.event.ActionEvent event) {
write = getClientField();
try {
dout.writeUTF(write);
dout.flush();
if (getClientArea()!=null){
setClientArea(getClientArea()+"\n"+write);
setClientField("");
}else {
setClientArea(write);
setClientField("");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(write);
}
我相信我理解这个问题,以及如何纠正它。
您正在为每个新连接使用唯一的线程 (chatHandler)。
该线程在连接时自动写入 "Hello",但此后专门用于读取消息(在 while 循环中您只读取 din)并相应地更新控制台。由于每个线程都在管理对 din 的引用,因此所有传入的消息都是正常的。
但是,回写到客户端(serverSend)似乎不是在一个线程中;它由按钮事件触发。此时,dout 将是对最近连接的引用,而不是对打算获取消息的客户端的引用。这就是最近的客户端收到所有未来消息的原因。
更正是为目标客户选择正确的'dout'。当服务器 'operator' 选择回写消息(单击发送按钮)时,您需要以某种方式为该客户端获取正确的 'dout'。
一种方法是在创建线程之前建立 dout(使用套接字),并维护每个客户端之间的关系,以及它对应的 dout(即在 Map 中)。
如果问题仍然不清楚(每个客户必须对 dout 有唯一的引用),请告诉我,我会尽力澄清。