我是使用Java创建服务器和多个客户端的概念的新手,所以如果这是一个明显的修复,请道歉。我一直在尝试编写一个jframe聊天程序,它有一个服务器和两个客户端,目前它们都使用相同的端口。无论客户端发送什么数据,都将传递给服务器,服务器将显示它。到目前为止,代码执行此操作,但是,我还想将所述数据传递给其他客户端。我正在尝试编写程序代码,以便我可以指定发送数据的客户端。
代码如下:
服务器代码。
package Chats;
import java.io.*;
import java.net.*;
public class Chat_Server extends javax.swing.JFrame
{
static ServerSocket ss;
static Socket s;
static DataInputStream din;
static DataOutputStream dout;
public Chat_Server()
{
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
Msg_Area = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
Msg_Area.setColumns(20);
Msg_Area.setRows(5);
jScrollPane1.setViewportView(Msg_Area);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(32, 32, 32)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 332, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(36, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(24, 24, 24)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 237, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(39, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
public static void main(String args[])
{
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Chat_Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Chat_Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Chat_Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Chat_Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new Chat_Server().setVisible(true);
}
});
String msgin = "";
try
{
ss = new ServerSocket(1201); // Server starts at 1201 port number
s = ss.accept(); // Now server will accept the connections.
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
while(!msgin.equals("exit"))
{
msgin = din.readUTF();
Msg_Area.setText(Msg_Area.getText().trim() + "\n Client: \t" + msgin); // Displaying the message from client
}
}
catch(Exception e)
{
}
}
// Variables declaration - do not modify
private static javax.swing.JTextArea Msg_Area;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration
}
客户代码。
package Chats;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
public class Chat_Client extends javax.swing.JFrame
{
static Socket s;
static DataInputStream din;
static DataOutputStream dout;
public Chat_Client()
{
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
Msg_Text = new javax.swing.JTextField();
jScrollPane1 = new javax.swing.JScrollPane();
Msg_Area = new javax.swing.JTextArea();
Msg_Send = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
Msg_Text.setText("jTextField1");
Msg_Area.setColumns(20);
Msg_Area.setRows(5);
jScrollPane1.setViewportView(Msg_Area);
Msg_Send.setText("jButton1");
Msg_Send.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Msg_SendActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(29, 29, 29)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 332, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addComponent(Msg_Text, javax.swing.GroupLayout.PREFERRED_SIZE, 257, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE)
.addComponent(Msg_Send)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(19, 19, 19)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 196, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(Msg_Text, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(Msg_Send))
.addGap(23, 23, 23))
);
pack();
}// </editor-fold>
private void Msg_SendActionPerformed(java.awt.event.ActionEvent evt) {
try
{
String msgout = "";
msgout = Msg_Text.getText().trim();
dout.writeUTF(msgout);
}
catch (Exception e)
{
//handle exceptions here.
}
}
public static void main(String args[])
{
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Chat_Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Chat_Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Chat_Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Chat_Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new Chat_Client().setVisible(true);
}
});
try
{
s = new Socket ("127.0.0.1", 1201); // Here the ip ddress is local address.
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
String msgin = "";
while (!msgin.equals("exit"))
{
msgin = din.readUTF();
Msg_Area.setText(Msg_Area.getText().trim() + "\n Server: \t" + msgin);
}
}
catch(Exception e)
{
//Exception Code
}
}
// Variables declaration - do not modify
private static javax.swing.JTextArea Msg_Area;
private javax.swing.JButton Msg_Send;
private javax.swing.JTextField Msg_Text;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration
}
我为另一个客户设置了另一个页面,但到目前为止,代码是第一个客户端页面的副本,所以没有任何意义发布它。
答案 0 :(得分:0)
您只接受ss.accept()
的单个客户,就是这样。 ServerSocket #acac等待单个传入客户端连接并创建一个Socket对象。为了接受多个连接,您需要不断循环ss.accept()以继续侦听其他客户端连接。建立新连接后,您可以将其添加到列表中。 (我没有测试过代码,只是指出你需要的方向)
public static void main(String []args) throw Exception{
ServerSocket serverSocket = new ServerSocket(1201);
List<Socket> clients = new ArrayList<Socket>();
while(true) {//continuously listening for a new connection
Socket client = serverSocket.accept();
clients.add(client);
}
}
现在问题是,如果你的服务器经常监听连接,它会阻塞你的线程。因此,每次添加连接时,都会生成一个新线程来处理它。
public static void main(String []args) throw Exception{
ServerSocket serverSocket = new ServerSocket(1201);
List<Socket> clients = new ArrayList<Socket>();
while(true) {
Socket client = serverSocket.accept();
clients.add(client);
new Thread(new Runnable(){
public void run(){
//Handle socket here
}
}).start();
}
}
如果你想避免像这样创建多个线程,那么你将不得不使用nio socketchannels。