[英]How can I get my chat to accept more than one client?
我正在嘗試創建一個多客戶端到服務器的聊天。 這在一對一聊天時工作正常,但是當我嘗試運行另一個客戶端並連接它時,它不會通過/連接。 我在線程上遺漏了什么嗎? 我只添加了沒有導入的 Server 和 Client 類,有一個主類詢問用戶是要成為服務器還是客戶端(加入)並詢問端口......
public Server(int port, String name) {
frame = new JFrame("Messenger");
frame.setSize(600, 400);
hostport = port;
userText = new JTextField(); //Input text field
userText.setEditable(false); //Can't write until connected with someone
userText.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
sendMessage(event.getActionCommand(), name);
userText.setText("");
}
}
);
JButton jbutton = new JButton("Browse File");
JPanel messagePanel = new JPanel(new BorderLayout());
jbutton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
JFileChooser file = new JFileChooser();
file.setCurrentDirectory(new File(System.getProperty("user.home")));
FileNameExtensionFilter filter = new FileNameExtensionFilter("*.Images", "jpg","gif","png");
file.addChoosableFileFilter(filter);
int result = file.showSaveDialog(null);
if(result == JFileChooser.APPROVE_OPTION){
File selectedFile = file.getSelectedFile();
String path = selectedFile.getAbsolutePath();
userText.setText(path);
}
else if(result == JFileChooser.CANCEL_OPTION){
System.out.println("No File Select");
}
}
}
);
messagePanel.add(userText, BorderLayout.CENTER);
messagePanel.add(jbutton, BorderLayout.EAST);
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow));
chatWindow.setSize(400, 300);
frame.add(chatWindow, BorderLayout.CENTER);
frame.add(messagePanel, BorderLayout.SOUTH);
frame.setVisible(true);
t = new Thread(new Runnable() {
@Override
public void run(){
startRunning(name);
}
});
}
//set up and run de server
public void startRunning(String servName) {
try {
server = new ServerSocket(hostport);
while(true) {
try {
waitForConnection(servName);
setupStreams();
whileChatting();
}catch(EOFException eofException) {
showMessage("\n Connection Ended");
}finally {
close();
}
}
}catch(IOException ioException) {
ioException.printStackTrace(); //prints error
}
}
//wait for connection
private void waitForConnection(String servName) throws IOException{
showMessage("Waiting for someone to connect");
socket = server.accept();
showMessage("\nNow connected to: " + socket.getInetAddress() + servName);
}
//get stream to send and receive data
private void setupStreams() throws IOException{
output = new ObjectOutputStream(socket.getOutputStream());
output.flush();
input = new ObjectInputStream(socket.getInputStream());
showMessage("\n Streams Are now Set up \n");
}
//during the chat conversation
private void whileChatting() throws IOException{
String message = "You are now connected ";
showMessage(message);
ableToType(true);
do {
try {
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException classNotFoundException) {
showMessage("\n Error on input \n");
}
}while(!message.equals("CLIENT - END"));
}
//Close streams and sockets in java after done chatting
private void close() {
showMessage("\n Closing connections... \n");
ableToType(false);
try {
output.close(); //stream close
input.close(); //stream close
socket.close(); //connection close
}catch(IOException ioException) {
ioException.printStackTrace(); //prints error
}
}
//sends message to the client
private void sendMessage(String message, String name) {
try {
output.writeObject(name + ": " + message);
output.flush(); //cleans input stream, flush all the extra bites
showMessage("\n " + name + ": " + message);
}catch(IOException ioException) {
chatWindow.append("\n Error ");
}
}
//updates chat window (displays messages)
private void showMessage(final String text) {
SwingUtilities.invokeLater( //allows thread that updates parts of the GUI
new Runnable() {
public void run() {
chatWindow.append(text);
}
}
);
}
//lets the user type text into their box
private void ableToType(final boolean tof) {
SwingUtilities.invokeLater( //allows thread that updates parts of the GUI
new Runnable() {
public void run() {
userText.setEditable(tof);
}
}
);
}
public Client(String IPAdress, int port, String name){
frame = new JFrame("Client");
frame.setSize(600, 400);
serverIP = IPAdress;
HostPort = port;
userText = new JTextField(); //Input text field
userText.setEditable(false); //Can't write until connected with someone
userText.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
sendData(event.getActionCommand(), name);
userText.setText("");
}
}
);
JButton jbutton = new JButton("Browse File");
JPanel messagePanel = new JPanel(new BorderLayout());
jbutton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
JFileChooser file = new JFileChooser();
file.setCurrentDirectory(new File(System.getProperty("user.home")));
FileNameExtensionFilter filter = new FileNameExtensionFilter("*.Images", "jpg","gif","png");
file.addChoosableFileFilter(filter);
int result = file.showSaveDialog(null);
if(result == JFileChooser.APPROVE_OPTION){
File selectedFile = file.getSelectedFile();
String path = selectedFile.getAbsolutePath();
userText.setText(path);
}
else if(result == JFileChooser.CANCEL_OPTION){
System.out.println("No File Select");
}
}
}
);
//add JTextField to CENTER and button to EAST
messagePanel.add(userText, BorderLayout.CENTER);
messagePanel.add(jbutton, BorderLayout.EAST);
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow));
chatWindow.setSize(400, 300);
frame.add(chatWindow, BorderLayout.CENTER);
frame.add(messagePanel, BorderLayout.SOUTH);
frame.setVisible(true);
t = new Thread(new Runnable() {
@Override
public void run(){
startRunnable();
}
});
}
//connect to server
public void startRunnable() {
try {
while(true) {
try {
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException eofException) {
showMessage("\n Connection Ended");
}finally {
close();
}
}
}catch(IOException ioException) {
ioException.printStackTrace(); //prints error
}
}
//connection to server
private void connectToServer() throws IOException{
showMessage("\n Attempting connection");
connection = new Socket(InetAddress.getByName(serverIP),HostPort);
showMessage("\nNow connected to " + connection.getInetAddress().getHostName());
}
//get stream to send and receive data
private void setupStreams() throws IOException{
try {
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("llegue?");
showMessage("\n Streams Are now Set up \n");
}catch(IOException ioException) {
chatWindow.append("\n Error seting up stream");
}
}
//during the chat conversation
private void whileChatting() throws IOException{
ableToType(true);
do {
try {
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException classNotFoundException) {
showMessage("\n Error on input \n");
}
}while(!message.equals("SERVER - END"));
}
//Close streams and sockets in java after done chatting
private void close() {
showMessage("\n Closing connections... \n");
ableToType(false);
try {
output.close(); //stream close
input.close(); //stream close
connection.close(); //connection close
}catch(IOException ioException) {
ioException.printStackTrace(); //prints error
}
}
//sends message to the client
private void sendData(String message, String name) {
try {
output.writeObject(name + ": "+message);
output.flush(); //cleans input stream, flush all the extra bites
showMessage("\n" + name + ": "+ message);
}catch(IOException ioException) {
chatWindow.append("\n Error ");
}
}
//updates chat window (displays messages)
private void showMessage(final String M) {
SwingUtilities.invokeLater( //allows thread that updates parts of the GUI
new Runnable() {
public void run() {
chatWindow.append(M);
}
}
);
}
//lets the user type text into their box
private void ableToType(final boolean tof) {
SwingUtilities.invokeLater( //allows thread that updates parts of the GUI
new Runnable() {
public void run() {
userText.setEditable(tof);
}
}
);
}
}
我相信您僅在當前客戶端斷開連接時使用server.accept()
。
為了接收更多的連接,你需要主動監聽新的連接。 因此,在這種情況下,您需要一個主動偵聽和接受新連接的線程,以及另一個檢查您已經擁有的套接字是否有任何數據的線程。
也許在這種情況下使用 UDP 會更好,因為您可以為每個人打開一個端口並在那里監聽,並讓每個客戶端在它發送的數據上標識自己,這樣您就不需要監聽端口連接和也同時給每個客戶。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.