java - 如何在运行方法之外发送对象?
问题描述
我希望能够使用我的sendMessage()
方法向我的客户发送一些东西,同时还等待客户消息(客户应该能够这样做)。我试图在任何地方定义 Socket 和 Streamobjects,但我认为我并不真正了解它们是如何工作的。
public class Server extends Thread{
private ObjectOutputStream oos;
public void sendMessage(String message){
try
{
oos.writeObject(message);
} catch (IOException e)
{
e.printStackTrace();
}
}
public void run() {
try {
ServerSocket server = new ServerSocket(4444);
Socket socket = server.accept();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
this.oos = oos;
while(true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Server Received: " + message);
ois.close();
socket.close();
}
} catch (Exception e) {
}
}
public class Main {
public static void main(String[] args)
{
Server s = new Server();
s.start();
new Client().start();
s.sendMessage("test");
}
编辑
好的,我尝试为每个客户端创建一个线程,但我仍然遇到无法访问 objectoutputstream 的问题...
public class SuperServer {
private Server s = new Server();
public void startServer(){
s.setDaemon(true);
s.start();
if(s.isAlive()){
System.out.println("server started");
}
}
public void sendMessage(String message) throws IOException
{
s.handler.sendMessage(message);
}
}
public class Server extends Thread {
ServerSocket server;
Socket socket;
ServerHandler handler;
public void run()
{
try {
server = new ServerSocket(4444);
while (true)
{
socket = server.accept();
ServerHandler serverHandler = new ServerHandler(socket);
handler = serverHandler;
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public class ServerHandler extends Thread {
protected Socket socket;
private ObjectOutputStream oos;
private ObjectInputStream ois;
public ServerHandler(Socket socket){
this.socket = socket;
}
public void sendMessage(String message) throws IOException
{
oos.writeObject(message);
}
public void run()
{
try(
ServerSocket server = new ServerSocket(4444);
Socket socket = server.accept();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
)
{
this.socket = socket;
this.oos = oos;
while (true)
{
String message = (String) ois.readObject();
System.out.println("Server Received: " + message);
}
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) throws IOException
{
SuperServer s = new SuperServer();
s.startServer();
SuperClient c = new SuperClient();
c.clientStart();
Scanner sc = new Scanner(System.in);
System.out.println("input 1:");
int a = Integer.parseInt(sc.nextLine());
if(a == 1) s.sendMessage("test");
}
}
解决方案
您错误地使用了线程和套接字。
1)在服务器端,通常您希望为每个与客户端的新连接创建一个新线程,以并行化服务器与其客户端之间的通信。
在这里,您为整个服务器处理创建一个线程......
2)这会产生另一个问题,因为Threads.start()
现在不一定要运行线程。所以在这里 :
Server s = new Server();
s.start();
new Client().start();
s.sendMessage("test");
s.sendMessage("test");
可以在之前调用, Server
线程Client
被执行和终止。所以ObjectOutputStream
场可能是静止的null
。
3) 读取第一条消息后关闭 ServerSocket。
所以即使 s.sendMessage("test");
在正确的时间被调用(幸运),这次ois
也不会被关闭。null
所以总结一下:
- 在正确的时间执行事件。
- 仅在需要时创建新线程。这些不是细节。
- 如果您仍想发送/接收消息,请不要关闭套接字。
推荐阅读
- go - 无法跨文件使用包
- python - 如何在 python selenium 中停止 150 的元素列表长度上限?
- git - 合并名称带有斜线的分支时出错
- reactjs - 在 promise 中作为参数传递时数组未定义
- visual-studio-code - 如何从同一列开始缩进多行?
- java - 如何在java中删除/删除对象,以便下次使用编译器时出错
- asp.net - 如何在 Azure 虚拟机中部署 asp .net 网站?
- reactjs - react-datetime 下拉列表缺少样式(css)
- javascript - 为什么即使状态没有改变,这个自定义钩子也会渲染两次?
- javascript - 使用 TailwindCSS 和 JS 的响应式导航栏