![](/img/trans.png)
[英]Encrypting communication in Eneter between single server and multiple clients, each using different key
[英]Communication deadlock in single server and multiple clients
我是Java初學者,正在為聊天服務器應用程序編程。 該應用程序可促進n個客戶之間的聊天
當前問題
在我的代碼中, Chatinterface class
下面是客戶端類。 打開2個Chatinterface
類的實例后,當我嘗試通過在文本區域中輸入消息進行通信時。 我沒有在另一個客戶端實例窗口中收到消息,反之亦然。 我的套接字無法通信或存在其他問題。
預期產量
客戶端和客戶端都必須進行通信,並且消息必須顯示在相應的窗口中。
任何人都可以告訴我發生了什么問題以及在哪里可以更正我的代碼?
無論如何,我都同時粘貼了客戶端代碼和服務器代碼以進行詳細分析。
package stack;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
class Chatinterface implements ActionListener {
private JFrame frame;
JTextArea textArea_1;
JTextArea textArea_2;
JButton btnNewButton;
JButton btnNewButton_1;
Socket client;
BufferedReader read;
PrintWriter write;
String getmsg;
String gettext;
public Chatinterface(){
communicate();
displaygui();
}
private void communicate() {
// TODO Auto-generated method stub
try {
client = new Socket("localhost",3420);
read = new BufferedReader(new InputStreamReader(client.getInputStream()));
write = new PrintWriter(client.getOutputStream(),true);
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void displaygui() {
frame = new JFrame();
frame.setResizable(false);
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SpringLayout springLayout = new SpringLayout();
frame.getContentPane().setLayout(springLayout);
textArea_1 = new JTextArea();
springLayout.putConstraint(SpringLayout.NORTH, textArea_1, 171, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, textArea_1, 10, SpringLayout.WEST, frame.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, textArea_1, -10, SpringLayout.SOUTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, textArea_1, 340, SpringLayout.WEST, frame.getContentPane());
frame.getContentPane().add(textArea_1);
textArea_2 = new JTextArea();
textArea_2.setWrapStyleWord(true);
textArea_2.setEditable(false);
springLayout.putConstraint(SpringLayout.NORTH, textArea_2, 10, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, textArea_2, 0, SpringLayout.WEST, textArea_1);
springLayout.putConstraint(SpringLayout.SOUTH, textArea_2, 160, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, textArea_2, 0, SpringLayout.EAST, textArea_1);
frame.getContentPane().add(textArea_2);
btnNewButton = new JButton("Send");
springLayout.putConstraint(SpringLayout.NORTH, btnNewButton, -76, SpringLayout.SOUTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, btnNewButton, 5, SpringLayout.EAST, textArea_1);
springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton, -27, SpringLayout.SOUTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnNewButton, 82, SpringLayout.EAST, textArea_1);
frame.getContentPane().add(btnNewButton);
btnNewButton.addActionListener(this);
btnNewButton.setActionCommand("S");
btnNewButton_1 = new JButton("Logout");
springLayout.putConstraint(SpringLayout.NORTH, btnNewButton_1, 50, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, btnNewButton_1, -65, SpringLayout.EAST, btnNewButton);
springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton_1, 108, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnNewButton_1, 0, SpringLayout.EAST, btnNewButton);
frame.getContentPane().add(btnNewButton_1);
btnNewButton_1.addActionListener(this);
btnNewButton_1.setActionCommand("L");
frame.setVisible(true);
}
public static void main(String args[])
{
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new Chatinterface();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
@Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.getActionCommand().equals("S"))
{
String gettext2;
gettext2 = textArea_1.getText();
textArea_2.append(gettext2);
textArea_1.setText("");
write.println(gettext2);
}
if(arg0.getActionCommand().equals("L")){
try {
read.close();
write.close();
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
這是服務器類的代碼
package stack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class Server1 {
public static void main(String[] args) throws Exception {
Socket s;
ServerSocket server = new ServerSocket(3420);
while(true)
{
s = server.accept();
Handler handler1 = new Handler(s);
Thread t1 = new Thread(handler1);
t1.start();
}
}
}
這是處理程序類
package stack;
import java.io.*;
import java.net.*;
public class Handler implements Runnable {
Socket s;
String getmsg = null;
String sendmsg;
public Handler(Socket s) {
this.s = s;
}
public void run() {
try {
BufferedReader reader1;
PrintWriter writer1;
reader1 = new BufferedReader(new InputStreamReader(
s.getInputStream()));
writer1 = new PrintWriter(s.getOutputStream(), true);
sendmsg = reader1.readLine();
while (true) {
if (reader1 == null) {
s.close();
} else {
writer1.println(sendmsg);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
正如ben75所說,該代碼很難閱讀並且有一些錯誤。 讓我提供一些建議,以幫助您:
1-不要在構造函數內創建功能。 這就是您在Chatinterface中所做的。 構造函數應僅創建對象。 然后,您可以添加一個名為“ execute”的方法來完成工作。
private void execute()
{
...
}
2-我還沒有測試通信部分,但是它應該可以在客戶端和服務器之間正常通信。 我運行Chatinterface,代碼正確到達這一行:
write.println(gettext2);
3-之所以看不到該消息,是因為在構造函數中,它正在調用communication和displaygui。 通訊中的代碼是應該顯示從服務器發回的消息的代碼:
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}
但是此代碼在開始時僅執行一次,getmsg為null,執行控制再也不會返回此代碼。 我假設您正在嘗試在客戶端中創建另一個線程,該線程將執行此代碼並進入無限循環。
如果您對通信客戶端服務器有疑問,可以使用Wireshark或tcpdump嗅探通信。
這里沒有僵局。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.