作为分配问题的一部分,我必须创建一个涉及客户端和服务器的应用程序。客户端允许用户连接到数据库,并在连接时从组合框中选择ID号,并从数据库中调用相关信息。信息首先存储在一个数组中,然后显示在相关的文本字段中。虽然我知道这样的数组是不合逻辑的,但这是分配中的一个要求所以我不得不使用它。服务器将在启动时显示,并且客户端已连接到该服务器。客户端界面将从服务器接收类似的响应并显示它。当用户选择“发送到服务器”时,它将在服务器上以及客户端界面上发送和显示信息。下面的图片显示了这是如何工作的以及错误是什么:
当用户点击“发送到服务器时,信息显示在客户端和服务器界面上,如下所示(这是它必须如何工作):
但是当我选择“发送到服务器”时,它将在服务器界面上正确显示详细信息,但客户端界面上显示的全部内容是用户连接到服务器,客户端编号和日期如下图所示:
但是当我与第三个人进行相同的处理时,它会在服务器中显示当前人员的详细信息,并在客户端界面上显示上一个人的详细信息,如下所示:
我已经完成了两个接口的整个编码,但我找不到问题(基于我的编码知识)。因此,我的问题是我在截图中演示了什么可能导致这个问题,如何在编码中修复它?
这是服务器类中的套接字编码(其余只是GUI编码):
try
{
//creates the server socket
ServerSocket ssocket = new ServerSocket(8100);
while(true)
{
//accepts the socket connection
Socket ssocket2 = ssocket.accept();
//increments the client number
clientNum++;
//creates the task class
ProcessClients pc = new ProcessClients(ssocket2,clientNum);
Thread thread = new Thread(pc);
//starts the thread
thread.start();
}
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "There was a problem connecting to the server", "SERVER ERROR", JOptionPane.ERROR_MESSAGE);
}
以下是服务器接口中ProcessClients类的编码:
class ProcessClients implements Runnable
{
//declares the socket
private Socket s;
//declares the client number
private int clientNumber;
//declares the array for the User object
ArrayList<User> array = new ArrayList<>();
//constructor
public ProcessClients(Socket soc, int clientNum)
{
this.s = soc;
clientNumber = clientNum;
}
@Override
public void run()
{
try
{
//declares DataInputStream for retrieving data
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
//message to be displayed showing client number and date of connection
String connected = "\nConnected to Client Number: " + clientNumber + "\nConnection Date: " + new Date();
jtaResults.append(connected);
while(true)
{
//message from the server responding to connection with client number, time and date
String response = "\nSERVER RESPONSE:\nConnected to server:\nClient Number: " + clientNumber + "\nConnection Date: " + new Date();
dos.writeUTF(response);
//input stream for the userID
int userID = dis.readInt();
//input stream for the lastName
String lastName = dis.readUTF();
//input stream for the firstName
String firstName = dis.readUTF();
//input stream for the age
int age = dis.readInt();
//creates user object
User use = new User(userID, firstName, lastName, age);
//Mutator methods to set user objects
use.setuserID(userID);
use.setlastName(lastName);
use.setfirstName(firstName);
use.setage(age);
//add object to array list
array.add(use);
//confirmation message regarding data received from client
String confirm = "\n SERVER RESPONSE:\nData received from client number: " + clientNumber +
"\nUser ID: " + userID + "\nFirst Name: " + firstName + "\nLast Name: " + lastName +
"\nAge: " + age + "\nDate received: " + new Date();
dos.writeUTF(confirm);
//displays the client number in the text area
jtaResults.append("\n\n Message from client number: " + clientNumber + "\n");
//displays the user ID in the text area
jtaResults.append("User ID: " + use.getuserID() + "\n");
//displays the first name in the text area
jtaResults.append("First Name: " + use.getfirstName() + "\n");
//displays the last name in the text area
jtaResults.append("Last Name: " + use.getlastName() + "\n");
//displays the age in the text area
jtaResults.append("Age: " + use.getage());
jtaResults.append("\nDate received: " + new Date());
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "There was a problem retrieving the data", "SERVER ERROR", JOptionPane.ERROR_MESSAGE);
}
}
以下是客户端类的编码(不包括GUI编码):
public ClientApp()
{
InterfaceProperties();
try
{
Socket csocket = new Socket("localhost", 8100);
input = new DataInputStream(csocket.getInputStream());
output = new DataOutputStream(csocket.getOutputStream());
String sresponse = input.readUTF();
jtaResults.append(sresponse);
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "There was a problem connecting to the server", "SERVER ERROR", JOptionPane.ERROR_MESSAGE);
}
}
//method for connecting to the database
private void ConnectDB()
{
String query = "Select * from studentinfo";
try
{
Class.forName("com.mysql.jdbc.Driver");
//connection
Connection conn = (Connection)
//root and username and password for access to the database
DriverManager.getConnection("jdbc:mysql://localhost:3306/studentdb","root","");
//create the statement that will be used
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
while(rs.next())
{
int userID = rs.getInt("userID");
cboIDNums.addItem(userID);
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "An error occured while trying to connect to the database", "CONNECTION ERROR!", JOptionPane.ERROR_MESSAGE);
}
}
public int idValue;
private void searchDB(int ID)
{
try
{
idValue = ID;
Class.forName("com.mysql.jdbc.Driver");
//connection
Connection conn = (Connection)
//root and username and password for access to the database
DriverManager.getConnection("jdbc:mysql://localhost:3306/studentdb","root","");
//create the statement that will be used
PreparedStatement stmt=conn.prepareStatement("Select * from studentinfo where userID = '" + ID + "'");
ResultSet rs = stmt.executeQuery();
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int numColumns = rsmd.getColumnCount();
rs.first();
int rowcount = 0;
do
{
rowcount++;
}
while (rs.next());
rs.first();
int rowindex = 0;
Object array2D[][] = new Object[rowcount][];
do
{
array2D[rowindex] = new Object[numColumns];
for (int i = 0; i < numColumns; i++)
{
array2D[rowindex][i] = rs.getObject(i + 1);
}
rowindex++;
}
while (rs.next());
jtfLastName.setText(array2D[0][2].toString());
jtfFirstName.setText(array2D[0][1].toString());
jtfAge.setText(array2D[0][3].toString());
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "There was a problem retrieving data", "SERVER ERROR", JOptionPane.ERROR_MESSAGE);
}
}
//declarng a click function
boolean clicked = true;
//method for the action listener
private void btnConnectOptionActionPerformed(java.awt.event.ActionEvent evt)
{
if(clicked)
{
//changes the butten text from 'Connect' to 'Disconnect'
btnConnectOption.setText("Disconnect");
clicked = false;
ConnectDB();
}
else
{
//changes the button text from 'Disconnect' to 'Connect'
btnConnectOption.setText("Connect");
clicked = true;
//resets the text fields
jtfAge.setText("");
jtfFirstName.setText("");
jtfLastName.setText("");
//resets the combo box
cboIDNums.removeAllItems();
try
{
Class.forName("com.mysql.jdbc.Driver");
//connection
Connection conn = (Connection)
//root and username and password for access to the database
DriverManager.getConnection("jdbc:mysql://localhost:3306/studentdb","root","");
//closes the database connection
conn.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "The database does not want to disconnect", "DISCONNECTION ERROR", JOptionPane.ERROR_MESSAGE);
}
}
}
//method for the action listener
private void btnSendToServerActionPerformed(java.awt.event.ActionEvent evt)
{
try
{
int userIDs = Integer.parseInt(cboIDNums.getSelectedItem().toString());
String lastNames = jtfLastName.getText();
String firstNames = jtfFirstName.getText();
int ages = Integer.parseInt(jtfAge.getText());
output.writeInt(userIDs);
output.writeUTF(lastNames);
output.writeUTF(firstNames);
output.writeInt(ages);
output.flush();
jtfFirstName.setText("");
jtfLastName.setText("");
jtfAge.setText("");
String receive = input.readUTF();
jtaResults.append(receive);
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, "An error occured loading data from text fields!\nFields empty!", "ERROR!", JOptionPane.ERROR_MESSAGE);
}
}
private void cboIDNumsActionPerformed(java.awt.event.ActionEvent evt)
{
try
{
idValue = Integer.parseInt(cboIDNums.getSelectedItem().toString());
searchDB(idValue);
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "Database disconnected", "DISCONNECT SUCCESSFUL", JOptionPane.PLAIN_MESSAGE);
}
}
答案 0 :(得分:0)
它闻起来像是缓冲冲洗效果。尝试在dos.flush()
方法中最后一次调用dos.write*
后添加ProcessClients.run
。