【发布时间】:2017-05-22 21:27:08
【问题描述】:
我想做一个游戏(打野速度),玩家点击图腾,它会在屏幕上改变位置(我用的是swing,这并不重要),并且应该将本地化更改的信息发送给每个人。
我想创建一个服务器来获取玩家的点击,验证它并向所有人发送更新信息。 在这种情况下,如果有人点击了图腾,客户端会监听服务器,同时准备发送有关他自己点击的信息。 服务器监听每个人,同时准备向所有人发送信息。 我尝试像这样实现它: 服务器为每个玩家生成线程,监听内部点击并准备被中断以发送新的图腾本地化(我在 ExecutorService 上使用方法 shutdownNow,这会导致线程中的 IOException,这将使它们停止循环并发送有关新本地化的信息) 然后客户端得到它。 如果他点击,客户端也一样,线程被中断,而不是等待新的本地化它发送他的点击。
问题是我无法创建流。这是输出和代码
客户端:
2017-05-22T23:04:06.417Connected
2017-05-22T23:04:06.417Trying to make output
2017-05-22T23:04:06.417Trying to make input
服务器端:
2017-05-22T23:04:03.278Server Thread :Socket created
2017-05-22T23:04:03.294Server Thread :Waiting for client!
2017-05-22T23:04:06.385Server Thread :Correct, connected!
2017-05-22T23:04:12.239Trying to make input
客户端代码:
package client;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerConnection implements Runnable {
MainWindow frame;
Socket toServ;
Socket fromServ;
ServerSocket myServ;
ObjectOutputStream out;
ObjectInputStream reader;
public int x, y, totemx, totemy;
int i = 0;
public ServerConnection(MainWindow frame) {
try {
this.frame = frame;
myServ = new ServerSocket(1338);
toServ = new Socket("localhost", 1337);
fromServ = myServ.accept();
System.out.println(LocalDateTime.now() + "Connected");
try {
System.out.println(LocalDateTime.now() + "Trying to make output");
out = new ObjectOutputStream(new BufferedOutputStream(toServ.getOutputStream()));
} catch (IOException ex) {
Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(LocalDateTime.now() + "Trying to make input");
reader = new ObjectInputStream(new BufferedInputStream(fromServ.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void run() {
System.out.println(LocalDateTime.now() + "Running");
while (true) {
try {
int xGot, yGot;
System.out.println(LocalDateTime.now() + "Waiting for params");
xGot = (int) reader.readInt();
yGot = (int) reader.readInt();
System.out.println(LocalDateTime.now() + "I got new params");
frame.refresh(xGot, yGot);
} catch (IOException ex) {
{
try {
System.out.println(LocalDateTime.now() + "Sending click thread: Sending my click");
out.writeInt(x);
out.writeInt(y);
System.out.println(LocalDateTime.now() + "Sent");
} catch (IOException ex1) {
Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex1);
}
}
}
}
}
}
服务器端代码 第一个文件:
package javaapplicationserwer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Japko
*/
public class Server{
public int x, y;
ServerSocket serv = null;
ExecutorService executor;
Server()
{
x = 10;
y = 50;
executor = Executors.newFixedThreadPool(4);
try {
serv = new ServerSocket(1337);
System.out.println(LocalDateTime.now() + "Server Thread :Socket created");
while (true) {
System.out.println(LocalDateTime.now() + "Server Thread :Waiting for client!");
Socket fromSocket = serv.accept();
Socket toSocket=new Socket(fromSocket.getInetAddress(),1338);
System.out.println(LocalDateTime.now() + "Server Thread :Correct, connected!");
ClientConnection temp = new ClientConnection(fromSocket,toSocket, this);
executor.submit(temp);
}
} catch (IOException ex) {
Logger.getLogger(JavaApplicationSerwer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void updateIt(int x, int y) {
System.out.println(LocalDateTime.now() + "Updating");
if (x == this.x && y == this.y) {
Random rand = new Random();
this.x = rand.nextInt(300);
this.y = rand.nextInt(300);
System.out.println(LocalDateTime.now() + "Updated");
executor.shutdownNow();
}
System.out.println(LocalDateTime.now() + "I notify");
}
}
第二个文件(实现runnable的类,由服务器为每个玩家创建):
package javaapplicationserwer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ClientConnection implements Runnable {
Socket fromSocket, toSocket;
InetAddress IP;
Server serv;
ObjectOutputStream out;
ObjectInputStream reader;
public ClientConnection(Socket fromSocket, Socket toSocket, Server serwer) {
this.fromSocket = fromSocket;
this.toSocket = toSocket;
this.serv = serwer;
try {
System.out.println(LocalDateTime.now() + "Trying to make input");
reader = new ObjectInputStream(new BufferedInputStream(fromSocket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(LocalDateTime.now() + "Trying to make output");
try {
out = new ObjectOutputStream(new BufferedOutputStream(toSocket.getOutputStream()));
} catch (IOException ex) {
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void run() {
while (true) {
System.out.println(LocalDateTime.now() + "Starting");
try {
int xGot, yGot;
while (true) {
System.out.println(LocalDateTime.now() + "Waiting for params");
try {
xGot = reader.readInt();
yGot = reader.readInt();
System.out.println(LocalDateTime.now() + "Got this");
//serv.wait();
System.out.println(LocalDateTime.now() + "Waited");
serv.updateIt(xGot, yGot);
System.out.println(LocalDateTime.now() + "Verified");
} catch (IOException ex) {
try {
out.writeInt(serv.x);
out.writeInt(serv.y);
} catch (IOException ex1) {
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex1);
}
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
} finally {
System.out.println(LocalDateTime.now() + "I'm not serving for you");
}
}
}
}
听起来客户端有配对输出(这意味着服务器有输入),然后客户端想要创建输入,但服务器从构造函数中逃脱,甚至不尝试进行输出。
提前感谢您的帮助。
【问题讨论】:
-
您是否尝试在 write 调用后添加
out.flush()?另外,您的 println 调试显示什么? -
“无法创建流”不是问题描述,“从构造函数中转义”也不是问题。
-
@Gray out.flush() 有帮助。谢谢
标签: java multithreading sockets