gpt4 book ai didi

java - 无法将多个客户端添加到此 Java 聊天中

转载 作者:行者123 更新时间:2023-12-01 10:12:56 24 4
gpt4 key购买 nike

我正在尝试使用 java 构建一个具有多个客户端和单个服务器的简单聊天应用程序,但我似乎一次不能拥有多个客户端类型。

当只有客户端和服务器时一切正常。

但是,当我尝试添加第二个客户端时,事情就出了问题。

第二个客户端能够建立连接,但随后代码的流部分中的某些内容似乎被阻塞,因为代码无法继续通过第二个客户端中的 setupStreams 点。

这是客户端:

package instantMessanger;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.Random;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;



public class ClientRunner {
public static void main(String[] args){
Client client = new Client("127.0.0.1"); //using local host
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.startRunning();
}
}

public class Client extends JFrame{

/**
* An Instant Messaging Client
*/
private static final long serialVersionUID = 1L;
private JTextField userText;
private JTextPane chatWindow;
private JScrollPane sPane;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private String serverIP;
private Socket connection;
private String ClientUserName;

//constructor
public Client(String host){
super("Client Instant Messanger");
serverIP = host;
userText = new JTextField();
userText.setEditable(false);
userText.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand()); //takes text from text area and sends it
userText.setText("");
}
}
);
add(userText, BorderLayout.NORTH);
//chatWindow = new JTextArea();
chatWindow = new JTextPane();
sPane = new JScrollPane(chatWindow);
add(sPane, BorderLayout.CENTER);
setSize(600, 300);
setVisible(true);
}

//start
public void startRunning(){
try{
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException e){
showMessage("\n Client terminated the connection ");
}catch(IOException i){
i.printStackTrace();
}finally{
cleanUp();
}
}

//connect to server
private void connectToServer() throws IOException{
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 6879);
showMessage("Connected to: " + connection.getInetAddress().getHostName());
}

//generate username with random (unique) number
private void generateUserName(){
ClientUserName = "CLIENT"+ (int)Math.floor(Math.random() * ( 10 ));
}

//set up streams to send and receive messages
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
}

//while chatting with server
private void whileChatting() throws IOException{
generateUserName();
ableToType(true);
do{
try{
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException c){
showMessage("\n user input not accepted");
}
}while(!message.equals("SERVER - END"));
}

//clean up
private void cleanUp(){
showMessage("\n Closing the chat!");
ableToType(false);
try{
output.close();
input.close();
connection.close();
}catch(IOException i){
i.printStackTrace();
}
}

//send message to server
private void sendMessage(String message){
try{
output.writeObject(ClientUserName + " — " + message);
output.flush();
showMessage("\n" + ClientUserName + " — " + message);
}catch(IOException ioE){
appendToPane(chatWindow, "\n Error sending message", Color.RED);
}
}

//change + update chatWindow
private void showMessage(final String message){
System.out.println("the message is: " + message + " ends here");
SwingUtilities.invokeLater(
//create the thread
new Runnable(){
public void run(){
if(message.contains("CLIENT")){
appendToPane(chatWindow, message, Color.blue); //append the message to the history
}else if(message.contains("SERVER")){
appendToPane(chatWindow, message, Color.MAGENTA);
}else{
appendToPane(chatWindow, message, Color.green);
}
}
}
);
}

//allow user to type into text box
private void ableToType(final boolean tof){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
userText.setEditable(tof);
}
}
);
}

//append to pane
private void appendToPane(JTextPane tp, String msg, Color c)
{
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);

int len = tp.getDocument().getLength();
tp.setCaretPosition(len);
tp.setCharacterAttributes(aset, false);
tp.replaceSelection(msg);
}



}

这是服务器:

package instantMessanger;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

public class ServerRunner {
public static void main(String[] args){
Server server = new Server();
server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //close when hit x
server.startRunning(); //run the server class
}
}

public class Server extends JFrame{

/**
* An Instant Messaging Server
*/
private static final long serialVersionUID = 3671904040330502199L;
private JTextField userText;
private JTextPane chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
private String text = "";

//constructor
public Server(){
super("Server Instant Messanger");
userText = new JTextField();
userText.setEditable(false); //before connected to anyone else, can't type
userText.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand()); //send the text when enter is hit
userText.setText(""); //after the text is sent, message field goes back to blank
}
}
);
add(userText, BorderLayout.NORTH);
chatWindow = new JTextPane();
add(new JScrollPane(chatWindow));
setSize(600, 300);
setVisible(true);
}

//set up and run the server
public void startRunning(){
try{
server = new ServerSocket(6879, 100); //port num is first arg
while (true){
try{
//connect and have conversation
waitForConnection();
setupStreams();
whileChatting();
}catch(EOFException eofException){
//when host ends the connection, throw and catch exception
showMessage("\n Server ended the connection");
}finally{
cleanUp();
}
}
}catch(IOException ioException){
ioException.printStackTrace();
}
}

//wait for connection, then display connection info
private void waitForConnection() throws IOException{
showMessage("Waiting for someone to connect ... \n");
connection = server.accept(); //accept a connection and create socket
new ThreadedSocket(connection).start();
showMessage("Connected to: "+ connection.getInetAddress().getHostName() );
}

public class ThreadedSocket extends Thread {
Socket socket;
ThreadedSocket( Socket socket ) {
this.socket = socket;
}
}

//get stream to send and receive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // stream for send message
output.flush();
input = new ObjectInputStream(connection.getInputStream()); //stream for receive message
}

//during the chat conversation
private void whileChatting() throws IOException{
ableToType(true); //allow the user to type
do{
try{
text = (String) input.readObject();
showMessage('\n' + text);
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n user input not accepted");
}
}while(!text.contains("END")); //if user types END, end convo
}

//close streams and sockets after done to cleanup
private void cleanUp() {
showMessage("\n Closing connections..... \n");
ableToType(false);
try{
output.close(); //close input
input.close(); //close output
connection.close(); //close the connection
}catch(IOException ioException){
ioException.printStackTrace();
}
}

//send a message to the client
private void sendMessage(String message){
try{
output.writeObject("SERVER - " + message); //replace server with username?
output.flush(); //flush the buffer
showMessage("\nSERVER - " + message);
}catch(IOException ioException){
appendToPane(chatWindow,"\n Error: Message not sent", Color.red);
}
}

//update the chatWindow
private void showMessage(final String text){
SwingUtilities.invokeLater( //create a thread that updates the GUI
new Runnable(){
public void run(){
if(text.contains("CLIENT")){
appendToPane(chatWindow, text, Color.blue); //append the message to the history
}else if(text.contains("SERVER")){
appendToPane(chatWindow, text, Color.MAGENTA);
}else{
appendToPane(chatWindow, text, Color.green);
}
}
}
);
}

//let the user type when connected
private void ableToType(final boolean tof){
SwingUtilities.invokeLater( //create a thread that updates the GUI
new Runnable(){
public void run(){
userText.setEditable(tof); //set to passed in true or false
}
}
);
}

//append to pane
private void appendToPane(JTextPane tp, String msg, Color c)
{
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);

int len = tp.getDocument().getLength();
tp.setCaretPosition(len);
tp.setCharacterAttributes(aset, false);
tp.replaceSelection(msg);
}


}

任何和所有的帮助将不胜感激!

最佳答案

您正尝试对服务器的所有连接使用一个变量。这不起作用,因为一旦创建新的套接字连接,以前的连接将被垃圾收集。当接受新连接时,请将其添加到列表中。我不会提供代码示例,因为这需要更改代码的大部分部分并且会使答案变得臃肿。

请注意,它还要求您为每个连接创建单独的输入/输出流,而现在一旦建立新连接,您就会覆盖先前连接的流。

关于java - 无法将多个客户端添加到此 Java 聊天中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36050339/

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