【发布时间】:2018-09-23 01:12:19
【问题描述】:
我不熟悉使用 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
}
我为另一个客户设置了另一个页面,但到目前为止,代码是第一个客户页面的副本,所以发布它没有意义。
【问题讨论】:
-
除非您想学习
nio(它提供了一种在单个服务器线程中工作的方法),否则您需要将线程引入您的服务器。当前服务器阻塞accept(),然后建立一个连接,然后阻塞read()。每个客户端都应该运行在一个唯一的线程中,这样主服务器就可以继续accept()新的连接。此外,您需要维护pool的活动连接,以便能够按需将消息写入多个客户端。如果您只有两个客户端,您可以稍微简化一下,但无论如何都需要多个线程。
标签: java sockets server client ports