如何让多个客户端连接到服务器 java
Posted
技术标签:
【中文标题】如何让多个客户端连接到服务器 java【英文标题】:How to have multiple clients connect to a server java 【发布时间】:2013-05-11 02:38:09 【问题描述】:我编写了一个基本的 isnatnt messager 程序,但它只允许一个客户端连接到服务器。我将在我的代码中进行哪些更改,以便它可以接受多个客户端,而不是让他们排队等待。
Client.java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.Font;
public class Client extends JFrame
private JTextField userText;
private JTextArea chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private String serverIP;
private Socket connection;
private JTextField UsernameField;
private String Username;
Color RED = new Color(255,0,0);
Color ORANGE = new Color(255,128,0);
Color YELLOW = new Color(255,255,0);
Color LIGHT_GREEN = new Color(51,255,51);
Color GREEN = new Color(0,255,0);
Color DARK_GREEN = new Color(0,102,0);
Color LIGHT_BLUE = new Color(51,51,255);
Color BLUE = new Color(0,0,255);
Color DARK_BLUE = new Color(0,0,102);
Color PURPLE = new Color(153,0,153);
//constructor
public Client(String host)
super("Azrin IM");
serverIP = host;
userText = new JTextField("Enter Message Here.");
userText.addMouseListener(new MouseAdapter()
public void mouseClicked(MouseEvent e)
if (userText.getText().equals("Enter Message Here.")) // User has not entered text yet
userText.setText("");
);
userText.setEditable(true);
UsernameField = new JTextField("Enter Username Here.");
UsernameField.addMouseListener(new MouseAdapter()
public void mouseClicked(MouseEvent e)
if (UsernameField.getText().equals("Enter Username Here.")) // User has not entered text yet
UsernameField.setText("");
);
add(new JLabel ("Enter Username Here."));
UsernameField.setEditable(true);
userText.addActionListener(
new ActionListener()
public void actionPerformed(ActionEvent event)
Username = UsernameField.getText();
sendMessage(event.getActionCommand());
userText.setText("");
UsernameField.setText("");
);
add(userText, BorderLayout.SOUTH);
add (UsernameField, BorderLayout.NORTH);
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow), BorderLayout.CENTER);
setSize(400,300);
setVisible(true);
//connect to server
public void startRunning()
try
connectToServer();
setupStreams();
whileChatting();
catch(EOFException eofException)
showMessage("\n Client terminated connection");
catch(IOException ioException)
ioException.printStackTrace();
finally
Disconnect();
//connect to server
private void connectToServer() throws IOException
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 6969);
showMessage("Connected to: " + connection.getInetAddress().getHostName() );
//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());
showMessage("\n Now connected to Server! \n");
//while chatting with server
private void whileChatting() throws IOException
ableToType(true);
do
try
message = (String) input.readObject();
showMessage("\n" + message);
catch(ClassNotFoundException classNotfoundException)
showMessage("\n I dont know that object type");
while(!message.equals(Username + ": END"));
//close the streams and sockets
private void Disconnect()
showMessage("\n Disconnected.");
ableToType(false);
try
output.close();
input.close();
connection.close();
catch(IOException ioException)
ioException.printStackTrace();
//send messages to server
private void sendMessage(String message)
try
output.writeObject(Username + ": " + message);
output.flush();
showMessage("\n" + Username + ": " + message);
if (message.equals("RED"))
chatWindow.setForeground(RED);
if (message.equals("ORANGE"))
chatWindow.setForeground(ORANGE);
if (message.equals("YELLOW"))
chatWindow.setForeground(YELLOW);
// I am aware I need to space these if staments better :) .
if (message.equals("LIGHT_GREEN"))
chatWindow.setForeground(LIGHT_GREEN);
if (message.equals("GREEN"))
chatWindow.setForeground(GREEN);
if (message.equals("DARK_GREEN"))
chatWindow.setForeground(DARK_GREEN);
if (message.equals("LIGHT_BLUE"))
chatWindow.setForeground(LIGHT_BLUE);
if (message.equals("BLUE"))
chatWindow.setForeground(BLUE);
if (message.equals("DARK_BLUE"))
chatWindow.setForeground(DARK_BLUE);
if (message.equals("PURPLE"))
chatWindow.setForeground(PURPLE);
catch(IOException ioException)
chatWindow.append("\n something messed up sending message hoss!");
//change/update chatWindow
private void showMessage(final String m)
SwingUtilities.invokeLater(
new Runnable()
public void run()
chatWindow.append(m);
);
//gives user permission to type crap into the text box
private void ableToType(final boolean tof)
SwingUtilities.invokeLater(
new Runnable()
public void run()
userText.setEditable(tof);
);
ClientTest.java
import javax.swing.JFrame;
public class ClientTest
public static void main(String[] args)
Client charlie;
charlie = new Client("69.125.13.88");
charlie.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
charlie.startRunning();
服务器.java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Server extends JFrame
private JTextField userText;
private JTextArea chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
//constructor
public Server()
super("Azrin IM Server");
userText = new JTextField();
userText.setEditable(false);
userText.addActionListener(
new ActionListener()
public void actionPerformed(ActionEvent event)
sendMessage(event.getActionCommand());
userText.setText("");
);
add(userText, BorderLayout.NORTH);
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow));
setSize(500,200);
setVisible(true);
//set up and run the server
public void startRunning()
try
server = new ServerSocket(6969, 100);
while(true)
try
waitForConnection();
setupStreams();
whileChatting();
catch(EOFException eofException)
showMessage("\n Server ended the connection! ");
finally
closeCrap();
catch(IOException ioException)
ioException.printStackTrace();
//wait for connection, then display connection information
private void waitForConnection() throws IOException
showMessage(" Waiting for someone to connect... \n");
connection = server.accept();
showMessage(" Now connected to " + connection.getInetAddress().getHostName());
//get stream to send and receive data
private void setupStreams() throws IOException
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Streams are now setup! \n");
//during the chat conversation
private void whileChatting() throws IOException
String message = " You are now connected! ";
sendMessage(message);
ableToType(true);
do
try
message = (String) input.readObject();
showMessage("\n" + message);
catch(ClassNotFoundException classNotFoundException)
showMessage("\n idk wtf that user sent!");
while(!message.equals("CLIENT - END"));
//close streams and sockets after you are done chatting
private void closeCrap()
showMessage("\n Closing connections... \n");
ableToType(false);
try
output.close();
input.close();
connection.close();
catch(IOException ioException)
ioException.printStackTrace();
//send a message to client
private void sendMessage(String message)
try
output.writeObject("Josh A - " + message);
output.flush();
showMessage("\nSERVER - " + message);
catch(IOException ioException)
chatWindow.append("\n ERROR: DUDE I CANT SEND THAT MESSAGE");
//updates chatWindow
private void showMessage(final String text)
SwingUtilities.invokeLater(
new Runnable()
public void run()
chatWindow.append(text);
);
//let the user type stuff into their box
private void ableToType(final boolean tof)
SwingUtilities.invokeLater(
new Runnable()
public void run()
userText.setEditable(tof);
);
ServerTest.java
import javax.swing.JFrame;
public class ServerTest
public static void main(String[] args)
Server sally = new Server();
sally.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sally.startRunning();
【问题讨论】:
这个问题在过去两天里被问了 3 次...从All about Sockets 和Concurrency 开始。您需要很好地理解这些主题才能继续进行,所以我建议您从一些简单的示例开始,然后逐步进行...... IK 什么是套接字。 IT 说了一些关于必须将 serverTest.java 以线程形式放在其他地方的内容。我该怎么做? 【参考方案1】:普通线程示例
这是“普通”线程示例,可能是您可能会发现的更常见示例之一。这样做的问题是您可能会失去对线程的控制,并且有数百个斜坡线程都在运行,消耗系统资源...
它很简单,并且确实展示了您需要实现的基本概念......
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TestSocketThread
// Need away to stop the program...
private static boolean acceptMore = true;
public static void main(String[] args)
new TestSocketThread();
public TestSocketThread()
ServerSocket serverSocket = null;
try
serverSocket = new ServerSocket(6969, 100);
while (acceptMore)
Socket socket = serverSocket.accept();
new Thread(new SocketThread(socket)).start();
catch (IOException exp)
exp.printStackTrace();
finally
try
serverSocket.close();
catch (Exception e)
public class SocketThread implements Runnable
private Socket socket;
public SocketThread(Socket socket)
this.socket = socket;
@Override
public void run()
// Process socket...
执行器服务示例
执行器服务更灵活,并提供对普通线程更好的管理控制,包括(根据此示例)固定线程池。
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorSocketTest
// Need away to stop the program...
private static boolean acceptMore = true;
public static void main(String[] args)
new ExecutorSocketTest();
public ExecutorSocketTest()
ServerSocket serverSocket = null;
ExecutorService executorService = Executors.newFixedThreadPool(100);
try
serverSocket = new ServerSocket(6969, 100);
while (acceptMore)
Socket socket = serverSocket.accept();
executorService.submit(new SocketCallable(socket));
catch (IOException exp)
exp.printStackTrace();
finally
try
serverSocket.close();
catch (Exception e)
executorService.shutdownNow();
/**
*
* @author swhitehead
*/
public class SocketCallable implements Callable
private Socket socket;
public SocketCallable(Socket socket)
this.socket = socket;
@Override
public Object call() throws Exception
// Process socket requests...
return null;
你的工作是现在离开并阅读有关Concurrency in Java的所有信息
【讨论】:
以上是关于如何让多个客户端连接到服务器 java的主要内容,如果未能解决你的问题,请参考以下文章
如何通过JMeter将多个MQTT客户端连接到单个iothub
多个客户端如何同时连接到服务器上的一个端口,比如80?(译)