gpt4 book ai didi

java - 编写点对点聊天系统时遇到问题

转载 作者:太空宇宙 更新时间:2023-11-04 11:52:09 25 4
gpt4 key购买 nike

这是我收到的问题陈述:

设计一个协议(protocol),其中服务器负责匹配两个聊天客户端。服务器在 TCP 端口上监听即将到来的连接。如果没有客户端连接到要配对的服务器,则服务器接受连接的客户端,并使其等待另一个客户端。为此,它会向连接客户端发送一条消息以等待。当收到此命令时,客户端构造另一个服务器套接字实例来监听端口。然后,客户端向服务器发送一条消息,其中包含新创建的服务器监听的端口号。当另一个客户端 C2 在 C1 等待期间寻求与服务器的连接时,服务器会通过向 C2 发送消息“PEER_LOC $h:$p”来通知 C2 C1 的存在,其中 $h 是 C1 的主机名(或 IP 地址),$p 是 C1 正在等待的端口号。 C2 收到此消息后,会使用获得的信息寻求与 C1 的连接。客户端从用户处获取消息。然后,两个客户端交换消息,直到任何一方发送流结束”(Linux 中的 Ctrl-D)。然后它们的守恒被终止。复杂的方法可能会使用多个线程、超时等,但在这个问题中不是必需的。

我的问题是将两个客户端连接到我的服务器。我运行我的服务器程序,然后运行另外两个客户端类,它们彼此重复,只是名称不同。我可以连接到其中一个,但另一个似乎永远等待。

这些是我开设的类(class)。

服务器:

package chatserver2;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
// import all the class that you will need for functionailty

// extends jframe to develop gui's in java
public class Server {

private static ObjectOutputStream output; // stream data out
private static ObjectInputStream input; // stream data in
private static ServerSocket server;
private static Socket connection; // socket means set up connetion between 2 computers

private static int n;

//Constructor
public static void main(String[] args) throws IOException {

Server obj = new Server();
obj.RunServer();

try {
while (true) {

Handler obj2 = new Handler();

obj2.start();
System.out.println("Accepted connection from "
+ connection.getInetAddress() + " at port "
+ connection.getPort());

n++;
System.out.println("Count " + n);
}
} finally {
connection.close();
}

}

public Server() {

}

// run the server after gui created
public void RunServer() {

try {
server = new ServerSocket(6789); // 1st number is port number where the application is located on the server, 2nd number is the amount of people aloud to connect
while (true) {

try {
waitForConnection(); // wait for a connection between 2 computers
setupStreams(); // set up a stream connection between 2 computers to communicate
whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException eofException) {

}
}
} catch (IOException ioException) {

ioException.printStackTrace();
}
}

//Wait for a connection then display connection information
private void waitForConnection() {

try {
connection = server.accept();
} catch (IOException ioexception) {

ioexception.printStackTrace();
}

}
// stream function to send and recive data

private void setupStreams() throws IOException {

output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in

}

// this code while run during chat conversions
private void whileChatting() throws IOException {

String message = "WAIT ";
sendMessage(message);

do {

try {

message = (String) input.readObject(); // stores input object message in a string variable

System.out.println("Message from Client " + message);
} catch (ClassNotFoundException classnotfoundException) {

}
} while (!message.equals("CLIENT - END"));// if user types end program stops

}

private void closeChat() {

try {

output.close();
input.close();
connection.close();

} catch (IOException ioexception) {

ioexception.printStackTrace();
}
}

// send message to the client
private void sendMessage(String message) {

try {

output.writeObject(message);
output.flush();

System.out.println("Message to client " + message);

} catch (IOException ioexception) {

}

}

public static class Handler extends Thread {

private Socket connection;

public Handler() {

String message = "WAIT";

}

public void run() {

System.out.println("Connect" + Server.connection);
while (true) {

try {
waitForConnection();
setupStreams();
whileChatting();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}

}

}

private void waitForConnection() {

System.out.println("server" + server);
try {
connection = server.accept();
} catch (IOException ioexception) {

ioexception.printStackTrace();
}
System.out.println("Connection" + connection);

}

private void setupStreams() throws IOException {

output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in

}

private void whileChatting() throws IOException {

String message = " You are now connected ";
sendMessage(message);

do {

try {

message = (String) input.readObject();

} catch (ClassNotFoundException classnotfoundException) {

}
} while (!message.equals("CLIENT - END"));

}

private void closeChat() {

try {

output.close();
input.close();
connection.close();

} catch (IOException ioexception) {

ioexception.printStackTrace();
}
}

static private void sendMessage(String message) {

try {

output.writeObject(message);
output.flush();

} catch (IOException ioexception) {

}

}

}
}

一个重复的客户端类 C1 或 C2:

package chatserver2;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// import all the class that you will need for functionailty

// extends jframe to develop gui's in java
public class Client1 extends JFrame {

private JTextField userInput; //
private JTextArea theChatWindow; //
private ObjectOutputStream output; // stream data out
private ObjectInputStream input; // stream data in

private Socket connection; // socket means set up connetion between 2 computers

//Constructor
public Client1() {

}

// run the server after gui created
public void RunClient() {

try {
connection = new Socket("localhost", 6789);// 1st number is port number where the application is located on the server, 2nd number is the amount of people aloud to connect
while (true) {

try {
// wait for a connection between 2 computers
setupStreams(); // set up a stream connection between 2 computers to communicate
whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException eofException) {

} finally {

closeChat();
}
}
} catch (IOException ioException) {

ioException.printStackTrace();
}
}

//Wait for a connection then display connection information
// stream function to send and recive data
private void setupStreams() throws IOException {

output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in

}

// this code while run during chat conversions
private void whileChatting() throws IOException {

String message = "";

do {
// have conversion while the client does not type end
try {

message = (String) input.readObject(); // stores input object message in a string variable
System.out.println("message " + message);
if (message.equals("WAIT")) {
ServerSocket server2 = new ServerSocket(5000);
System.out.println("Hello");
message = "5000";
sendMessage(message);

}
System.out.println("From server " + message);

} catch (ClassNotFoundException classnotfoundException) {

}
} while (!message.equals("CLIENT - END"));// if user types end program stops

}

private void closeChat() {

try {

output.close(); // close output stream
input.close(); // close input stream
connection.close(); // close the main socket connection

} catch (IOException ioexception) {

ioexception.printStackTrace();
}
}

// send message to the client
private void sendMessage(String message) {

try {

output.writeObject(" - " + message);
output.flush(); // send all data out

} catch (IOException ioexception) {

theChatWindow.append("\n ERROR: Message cant send");
}

}

//
//
public static void main(String[] args) {
Client1 obj = new Client1();
obj.RunClient();
}

}

我可以连接到我运行的第一个客户端,第二个客户端则永远等待。如有任何建议或意见,我们将不胜感激。

最佳答案

您正在阻止服务器周期。您应该为来自客户端的每个连接启动新线程。我会将 waitForConnection()RunServer 方法中服务器循环中的下游代码分开。所以你的 while 循环应该是这样的:

public static void RunClient() {
...
while (true) {
try {
final Server srv = waitForConnection(); // wait for a connection between 2 computers
new Thread(new Runnable() {
public void run() {
try {
srv.setupStreams(); // set up a stream connection between 2 computers to communicate
srv.whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException ex) {
// ex.printStackTrace();
}
}
}).start();
} catch (EOFException eofException) {

}
}

在这种情况下,您必须为每个客户端创建服务器实例,并且您的服务器声明应包含与客户端相关的非静态属性,例如:

public class Server {
private ObjectOutputStream output; // stream data out
private ObjectInputStream input; // stream data in
private static ServerSocket server;
private Socket connection; // socket means set up connetion between 2 computers
...

服务器创建应该在 waitForConnection() 内进行,如下所示:

private static Server waitForConnection() {
try {
Socket connection = server.accept();
return new Server(connection);
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}

这不是唯一的方法。您可以保留服务器类来负责在同一实例中运行主周期。但在这种情况下,我将创建一些与来自特定客户端的连接相关的附加类处理属性(连接、输入、输出)。

关于java - 编写点对点聊天系统时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41705820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com