这是我给出的问题陈述:
设计协议,服务器负责匹配两个chatt客户端。服务器侦听TCP端口以进行即将到来的连接。 如果没有客户端已连接到要配对的服务器,则服务器接受连接客户端,并使其等待另一个客户端。为此,它会向连接客户端发送一条消息以等待。收到此命令时,客户端构造另一个服务器套接字实例以侦听端口。然后,客户端向服务器发送一个mesagge,其中包含新创建的服务器侦听的端口号。 当另一个客户端C2在C1等待时寻求与服务器的连接时,服务器通过向C2发送消息“PEER_LOC $ h:$ p”通知C2存在C1,其中$ h是主机名(或IP)地址)C1和$ p是C1等待的端口号。在C2收到此消息后,它使用获取的信息寻求与C1的连接。客户端从用户获取消息。然后,两个客户端交换消息,直到任何一方发送流结束“(在Linux中为Ctrl-D)。然后终止它们的保存。复杂的方法可以使用多个线程,超时等,并且在该问题中不是必需的。
我的问题是将两个客户端连接到我的服务器。我运行我的服务器程序,然后运行另外两个只有不同名称的彼此重复的客户端类。我可以连接到其中一个只是另一个似乎永远等待。
这些是我运行的课程。
服务器:
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();
}
}
我可以连接到第一个运行第二个客户端的客户端等待永远。 任何建议或意见将不胜感激。
答案 0 :(得分:0)
您正在阻止服务器周期。您应该从客户端为每个连接启动新线程。我会在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) {
}
}
在这种情况下,您必须为每个客户端创建Server实例,并且您的服务器声明应包含与客户端相关的非静态道具,如:
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();
}
}
这不是唯一的方法。您可以保留Server类以负责在同一实例中运行主循环。但在这种情况下,我会创建一些与特定客户端连接相关的其他类处理属性(连接,输入,输出)。
答案 1 :(得分:0)
这可能会让你想到把它归结为本质,或者它可能不会,我真的不知道。
我
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server implements Runnable{
private final ServerSocket serverSocket;
private Socket clientBuffer;
public Server(int port) throws IOException {
this.serverSocket = new ServerSocket(port);
}
@Override
public void run() {
while(true) {
try {
if(clientBuffer != null) {
//Accept new connection and echo ip and port, as the assignment tells you to, then set clientBuffer to null and start the process again. Change Client accordingly.
}
} catch(Exception ex) {
System.err.println(ex.getMessage());
System.exit(1);
}
}
}
}