java - JavaFX 中的套接字通信
问题描述
我正在尝试开发一个能够管理三个或更多客户端的电子邮件服务器。现在我只关注第一个客户。我使用的机制是这样的:客户端将其电子邮件地址(字符串)发送到服务器,因此他可以进入正确的目录并从 .txt(即电子邮件)中提取文本。这是服务器目录的结构:
$package
|
+------------+----------------------------+
| | |
Server.java ServerController.java email@email.com/
|
+
+--------|---------+
1.txt 2.txt 3.txt
这是 ServerController 文件,它是执行线程的文件:
public class ServerController {
@FXML
private TextArea textarea;
public void initModel() {
try {
int i = 1;
ServerSocket s = new ServerSocket(5000);
while (true) {
Socket incoming = s.accept(); // si mette in attesa di richiesta di connessione e la apre
textarea.setText("Waiting for connections");
Runnable r = new ThreadedEchoHandler(incoming, i);
new Thread(r).start();
i++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
private int counter;
/**
* Constructs a handler.
*
* @param i the incoming socket
* @param c the counter for the handlers (used in prompts)
*/
public ThreadedEchoHandler(Socket in, int c) {
incoming = in;
counter = c;
}
public void run() {
String nomeAccount = "";
try {
//PHASE 1: The server receives the email
try {
InputStream inStream = incoming.getInputStream();
Scanner in = new Scanner(inStream);
nomeAccount = in.nextLine(); //ricevo il nome
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
incoming.close();
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
//PHASE 2: I'm getting all the emails from the files
File dir = new File(nomeAccount);
String[] tmp = new String[5];
ArrayList<Email> arr = new ArrayList<Email>();
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
int i = 0;
for (File file : dir.listFiles()) {
if (file.isFile()) {
Scanner input = new Scanner(System.in);
input = new Scanner(file);
while (input.hasNextLine()) {
tmp[i++] = input.nextLine();
}
input.close();
}
Date data = df.parse(tmp[4]);
arr.add(new Email((Integer.parseInt(tmp[0])), tmp[1], nomeAccount, tmp[2], tmp[3], data));
i = 0;
}
//PHASE 3: The server sends the ArrayList to the client
try {
ObjectOutputStream objectOutput = new ObjectOutputStream(incoming.getOutputStream());
objectOutput.writeObject(arr);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParseException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
incoming.close();
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
如您所见,我将其分为几个阶段以更好地理解机制。在客户端中,我有一个 DataModel,它可以记住电子邮件列表并与套接字建立连接。这是代码:
public void loadData() throws IOException {
Socket s = new Socket("127.0.0.1", 5000);
System.out.println("I've created the socket");
ArrayList<Email> email = new ArrayList<Email>();
//PHASE 1: The client sends a string to the server
try {
InputStream inStream = s.getInputStream();
OutputStream outStream = s.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
out.print(account); //Sends account name
//PHASE 2: The client receives the ArrayList with the emails
ObjectInputStream objectInput = new ObjectInputStream(s.getInputStream()); //Error Line!
try {
Object object = objectInput.readObject();
email = (ArrayList<Email>) object;
System.out.println(email.get(1));
} catch (ClassNotFoundException e) {
System.out.println("The list list has not come from the server");
e.printStackTrace();
}
} finally {
s.close();
}
//Casting the arrayList
emailList = FXCollections.observableArrayList(email);
//Sorting the emails
Collections.sort(emailList, new Comparator<Email>() {
public int compare(Email o1, Email o2) {
if (o1.getData() == null || o2.getData() == null) {
return 0;
}
return o1.getData().compareTo(o2.getData());
}
});
}
问题是,当我执行服务器时,我没有收到任何错误,但 GUI 没有加载,并且在提示符下我看不到任何输出。如果我执行客户端(在服务器运行时),我只会收到消息System.out.println("I've created the socket");
,但之后没有任何反应。我应该修改什么以让两个套接字进行通信?
解决方案
使用套接字根本不是一个好主意。您不需要直接连接。最好使用带有 GET 和 POST 的 REST 服务。
因此您可以管理任何客户数量。只需发送响应以获取和发布。您也可以使用令牌。
推荐阅读
- wso2 - 无法从 WSO2 API Manager 3.1.0 调解序列调用 WSO2 IS-KM 5.10.0 SCIM2
- amazon-redshift - Kinesis Firehose 将数据放入多个 Redshift 表中
- amazon-web-services - 如何在 AWS Certificate Manager 中切换证书?
- wxpython - RichTextCtrl 根据光标位置改变样式
- angular - 可以通过单击按钮在 Angular 应用程序中调用 .jar 文件或任何其他外部打包的库吗?
- python - 通过避免循环来向量化 pandas 中的代码
- javascript - 如何使用 Typescript 在 webdriverIO 中注册自定义命令
- flutter - 为什么我的 AsyncMemoizer 在 Flutter 中无法正常运行,我想停止不必要地重建我的小部件
- r - R Limitation? A + B - A = B
- vue.js - vue 上的 npm run serve 不服务于本地主机