我正在创建一个Java文件发送程序。现在我正在尝试实现聊天消息系统。
以下是调用服务器/客户端代码的代码:
if(host.isSelected()) {
Server server = new Server();
ServerChat serverChat = new ServerChat();
server.Thread();
serverChat.Thread();
}
else if(guest.isSelected()) {
Client client = new Client();
ClientChat clientChat = new ClientChat();
client.Thread();
clientChat.Thread();
}
这将调用以下类中的代码:ServerChat
public class ServerChat extends Main implements Runnable {
public static ServerSocket ss;
public static Socket s;
public static DataInputStream dis;
public static DataOutputStream dos;
public void Thread() {
(new Thread(new ServerChat())).start();
}
@Override
public void run() {
String variable = "";
try {
ss = new ServerSocket(1234);
s = ss.accept();
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
while (!variable.equals("exit")) {
variable = dis.readUTF();
chatText.setText(chatText.getText().trim() + "\n Client:\t" + variable);
}
} catch (Exception e) {
}
if (send.isSelected()) {
try {
String messageOut = "";
messageOut = chatText.getText().trim();
dos.writeUTF(messageOut);
} catch (Exception e) {
}
}
}
}
ClientChat代码:
public class ClientChat extends Main implements Runnable {
public void Thread() {
(new Thread(new ClientChat())).start();
}
@Override
public void run() {
try {
socket = new Socket("localhost", 1234);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
String variable = "";
while (!variable.equals("exit")) {
variable = dis.readUTF();
chatText.setText(chatText.getText().trim() + "\n Server:\t" + variable);
}
} catch (Exception e) {
}
if (send.isSelected()) {
try {
String messageOut = "";
messageOut = chatText.getText().trim();
dos.writeUTF(messageOut);
} catch (Exception e) {
}
}
}
}
他们能够相互连接,但数据没有发布到我在主类中创建的文本框中。 (主要所需的所有元素都是公开的)。
当我连接(通过locahost)时,我通过一个新类创建服务器并打开一个新线程
public class Server extends Main implements Runnable {
public ServerSocket welcomeSocket;
public String file;
public DataOutputStream dos;
public DecimalFormat df = new DecimalFormat("##, #00");
public BufferedReader inFromClient;
public void Thread() {
(new Thread(new Server())).start();
}
@Override
public void run() {
try {
InetAddress localaddr = InetAddress.getLocalHost();
chatText.append("Local IP Address : " + localaddr);
chatText.append("Local hostname : " + localaddr.getHostName());
String clientSentence = null;
String capitalizedSentence;
welcomeSocket = new ServerSocket(1234);
String file = "";
DecimalFormat df = new DecimalFormat("##, #00");
while (true) {
Socket connectionSocket = welcomeSocket.accept();
inFromClient
= new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
} catch (Exception e) {
chatText.append("Unable to create server");
chatText.append("Can't detect local host : " + e);
}
}
客户也是如此:
public class Client implements Runnable {
public DataOutputStream dos;
public DataInputStream dis;
public Socket skt;
public StringTokenizer st;
public void Thread() {
try {
dos = new DataOutputStream(skt.getOutputStream());
dis = new DataInputStream(skt.getInputStream());
} catch (Exception e) {
System.out.println(e.getMessage());
}
(new Thread(new Client())).start();
}
@Override
public void run() {
try {
InetAddress localaddr = InetAddress.getLocalHost();
skt = new Socket("localhost", 1234);
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
while (!Thread.currentThread().isInterrupted()) {
String data = dis.readUTF();
st = new StringTokenizer(data);
String CMD = st.nextToken();
JFileChooser open = new JFileChooser();
open.showOpenDialog(null);
File f = open.getSelectedFile();
String fileName = f.getAbsolutePath();
FileInputStream fs = new FileInputStream(fileName);
switch (CMD) {
case "CMD_SENDFILE":
try {
fileName = st.nextToken();
System.out.println("Receiving file...");
String path = System.getProperty("user.home");
File file = new File(path + "/Downloads" + fileName + ".txt");
FileOutputStream fos = new FileOutputStream(path);
InputStream input = skt.getInputStream();
byte[] buffer = new byte[1024];
int count, percent = 1;
while ((count = input.read(buffer)) > 0) {
percent = percent + 1;
fos.write(buffer, 0, count);
}
fos.close();
System.out.println("File was saved: " + path);
} catch (Exception e) {
DataOutputStream eDos = new DataOutputStream(skt.getOutputStream());
System.out.println(e.getMessage());
skt.close();
}
break;
}
}
/*String string = in.readLine();
System.out.println("Incoming: " + string + "\n");
System.out.println("Incoming: " + in.readLine() + "\n");
//in.close();*/
} catch (Exception e) {
System.out.println("Error could not connect\n");
}
}
}
答案 0 :(得分:2)
你的主要问题在于:
public class ClientChat extends Main implements Runnable {
你错误地使用了继承。不使用继承,以便一个实例可以与另一个实例共享变量,这是您尝试使用它的原因。相反,它主要用于分享行为。我强烈要求ClientChat不扩展Main,而是有一个Main字段,可以调用它的公共方法。
你的另外两个问题是较小的问题,但它们仍会让你头痛:
e.printStackTrace();
。setText(...)
调用。如果你使用普通的香草线程,那么可以通过SwingUtilities.invokeLater(new Runnable() {...});
完成。否则,请考虑使用SwingWorker,它将通过其发布/处理方法对帮助您自动执行此操作。你问过:
关于继承,有什么帖子我可以看一下调用ClientChat的主要字段吗?
查找“继承与组合” - 你将使用后者,这里的组合,而不是继承。
您可能希望使用代码的聊天引擎或“模型”部分在GUI或代码的“查看”部分之间来回传递信息。有几种方法可以做到这一点,但通常它们通过某种类型的“控制”类或类连接,称为“MVC”或“模型 - 视图 - 控制器”架构。