一个socket应用程序,有服务端、消费端和充值端。不同端通过对象处理流用一个MyTransaction类来进行信息传输。服务端监听端口,并开一个新线程对发来的信息执行相应操作。消费端向服务端发送消费请求,充值端向服务端发送充值请求。
\---v2
ConsumeClient.java
MyTransaction.java
RechargeClient.java
Server.java
MyTransaction.java
交易类,用于传输交易信息,实现了java.io.Serializable接口用于序列化。除了该有的账户名、金额、交易信息、是否成功外,还用了一个枚举类型来区分是消费请求还是充值请求。此外,还有应有的构造函数和GetSet方法。
Server.java
主函数中使用ServerSocket不断对指定端口进行监听是否有连接请求,通过 accept() 方法接受连接后创建一个实际的网络连接Socket。然后新开一个实现了Runnable接口的ClientHandler方法的线程,在线程中从客户端 Socket 获取输入输出流,并将输入输出流包装成ObjectInputStream/ObjectOutputStream。之后从流中读取MyTransaction对象,执行相应逻辑后修改MyTransaction对象信息重新发回客户端。同时由于涉及到多线程,于是使用Collections.synchronizedMap将Map变成线程安全的Map。
RechargeClient.java
循环读入用户输入,创建Socket连接向服务端发送信息,之后等待接收回复信息,输出结果。Socket连接不保持,每个请求都重新创建。
ConsumeClient.java
用户事件调度线程EDT:负责对GUI组件的渲染和刷新,它只有一个,一定要注意这个问题,它处理的就是事件队列里的事情,他通过调用事件处理器来响应用户交互。所有的事件处理都是在EDT上进行的。
- 不能在主线程更新UI操作或执行耗时操作
- 所有的耗时操作应在非EDT中执行
- 所有的更新UI操作应该在EDT中执行
在主函数中调用SwingUtilities.invokeLater()
在EDT队列尾部插入GUI界面生成事件,并等待异步执行。GUI绘制省略不说。输入信息点击按钮后执行handleTransaction()函数校验输入,通过后调用sendTransaction()方法发送交易信息。在sendTransaction()函数中,也是同充值端一样创建Socket连接向服务端发送信息,之后等待接收回复信息,输出结果。