ゲーム プログラムのクラスを常に 33 ミリ秒ごとに更新する Java クライアントがあります。問題は、同じクラスを受け取り、同期する必要がある 2 つのクライアントを開くと、サーバーを最初に起動または接続したユーザーによって結果が異なることです。その後、値は決して変化しませんが、サーバーが書き込みクラスを両方に送信していることを(今)知っています。私の家庭教師の講義ノートには、このように行うように書かれています
ObjectInput input;
input = new ObjectInputStream(socket.getInputStream());
serializableobject = (cast) input.readObject();
input.flush();
これは私が教えられた方法ですが、今ではそれを実装するようになりました(大学ではこれは必要ありませんでした)それは機能しません。私は文字通り何週間も何ヶ月も費やしてその理由を解明しようとしましたが、今日はなぜクラックしたと思いますが、それを修正する方法がわかりません. 基本的に最初から input.flush(); ObjectInput または ObjectInputStream には存在しないように見えるので、それを省略してテストしたところ、ブレークポイントを使用してクラスが美しく表示され、サーバークラスが送信されたことを確認し、ゲーム設定クラスのすべての変数を設定しました。サーバーからのこのクラスの次の更新で問題が発生しますが、解決するのに何年もかかりました。私が信じていることは、(私が諦めなければ)最初に送信されたオブジェクトを読み取り、それを入力ストリームに保持することです。次に、同じメソッドを呼び出すと、最初のオブジェクトが再び返されます。これは、家庭教師が講義スライドで言っているように、フラッシュしないためだと思います。出力ストリームには、私が使用するフラッシュがあります。また、ObjectInput と ObjectInputStream の両方を調べたところ、フラッシュ、代替、またはストリーム内の次のオブジェクトに移動する方法を確認できませんでした。後者は、ストリームがメモリ不足になる可能性があるまで継続的に成長するため、とにかく良い考えだとは思いません。とにかく、受信クラスとサーバーをここに示します。後者は、ストリームがメモリ不足になる可能性があるまで継続的に成長するため、とにかく良い考えだとは思いません。とにかく、受信クラスとサーバーをここに示します。後者は、ストリームがメモリ不足になる可能性があるまで継続的に成長するため、とにかく良い考えだとは思いません。とにかく、受信クラスとサーバーをここに示します。
import java.io.*;
import java.net.*;
import java.util.*;
public class BaseServer
{
private String result = null;
//for serializable class input stream
ObjectInput input;
// Declare client socket
Socket clientSocket = null;
// Declare output stream and string to send to server
DataOutputStream os = null;
// Declare input stream from server and string to store input received from server
BufferedReader is = null;
String responseLine;
//get ip
String serverAddress ;
// Create a socket on port 5000 and open input and output streams on that socket
public void setUpNetwork(String serverAd)
{
try
{
serverAddress = serverAd;
clientSocket = new Socket(serverAddress, 5000);
//string
os = new DataOutputStream(clientSocket.getOutputStream());
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//serial
input = new ObjectInputStream( clientSocket.getInputStream() );
}
catch (UnknownHostException e)
{
System.err.println("Don't know about host: hostname");
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to: hostname");
}
}
/*
* Used to communicate with server
* takes message to send and the object expecting the response
* 1 simple method to replace all but one of the below v1 methods
*/
public BaseSerialDataObjects serverTalk(String message){
sendStringMessage(message);
try {
BaseSerialDataObjects bSO = (BaseSerialDataObjects) input.readObject();
return bSO;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
////////Old v.1 methods for interacting with servers. I have now changed my mind
//and am using strings to send messages and serializable objects as return messages
//I have left these in as I have plans to reuse the most of the code in this game
public String read(){
// Write data to the socket
if (clientSocket != null && os != null && is != null)
{
try
{
os.writeBytes("ok \n");
return is.readLine(); // my bit
}
catch (UnknownHostException e)
{
System.err.println("Trying to connect to unknown host: " + e);
}
catch (IOException e)
{
System.err.println("IOException: " + e);
}
}
return responseLine;
}
//Sends messages to the server
public void sendStringMessage(String message){
// Write data to the socket
if (clientSocket != null && os != null && is != null){
try {
os.writeBytes( message + "\n" );
}
catch (UnknownHostException e){
System.err.println("Trying to connect to unknown host: " + e);
}
catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
/*
* V.1 method idea am leaving in for an option in future games
*/
public String getStringResult(String returnMessage)
{
String tempHolder = read();
if(tempHolder!=null)
{
String[] array = tempHolder.split("\\s+");
if(array[0].trim().equalsIgnoreCase(returnMessage))
{
result = null;
tempHolder = "";
for(int i = 1; i < array.length;i++)
{
tempHolder = tempHolder + array[i] + " ";
}
return tempHolder.trim();
}
else return null;
}
else
{
return null;
}
}
public synchronized void setResult(String res)
{
result = res;
}
public void closeConnections()
{
// Close the input/output streams and socket
try{
os.close();
is.close();
clientSocket.close();
}catch(Exception e)
{
System.err.println("Exception: " + e);
}
}
}
行: BaseSerialDataObjects bSO = (BaseSerialDataObjects) input.readObject();
以下の戻りbSO行にブレークポイントを配置したもので、サーバーにブレークポイントを配置し、クライアントを作成するクラスを返す直前に取得した異なる値をチェックしたにもかかわらず、最初と同じ値を持つクラスを常に表示します検査中にハングアップするので、正しいスレッドとクラス、およびすべてを確認できます
サーバー:
import java.io.*;
import java.net.*;
import java.*;
import java.util.regex.*;
public class TCPserver implements Runnable
{
static Socket server = null;
private static final int possibleNumberOfPlayers = 8;
private static final int amountOfPlayerInfoHeld = 6;
private int threadNumber;
private static ServerSettings gameSettings = new ServerSettings();
private static int numberOfSettings = 4;
//position 0 = name;
//position 1 = angle;
//position 2 = position x
//position 3 = position y
//position 4 = state
//position 5 = state in relation to server
//POssible states:
// connected
static PlayerPositionsSerial positions = new PlayerPositionsSerial();
public static void main( String args[] )
{
positions.playersArray = new String [possibleNumberOfPlayers][amountOfPlayerInfoHeld];
// Declare a server socket and a client socket for the server
ServerSocket service = null;
// Try to open a server socket on port 5000
try
{
service = new ServerSocket(5000);
server = service.accept();
Thread t0 = new Thread (new TCPserver(0));
t0.start();
server = service.accept();
Thread t1 = new Thread (new TCPserver(1));
t1.start();
server = service.accept();
Thread t2 = new Thread (new TCPserver(2));
t2.start();
server = service.accept();
Thread t3 = new Thread (new TCPserver(3));
t3.start();
server = service.accept();
Thread t4 = new Thread (new TCPserver(4));
t4.start();
server = service.accept();
Thread t5 = new Thread (new TCPserver(5));
t5.start();
server = service.accept();
Thread t6 = new Thread (new TCPserver(6));
t6.start();
server = service.accept();
Thread t7 = new Thread (new TCPserver(7));
t7.start();
/*server = service.accept();
Thread t8 = new Thread (new TCPserver(8));
t8.start(); */
}
catch (IOException e)
{
System.out.println(e + "Error B");
}
}
public void run()
{
// Declare an input stream and String to store message from client
BufferedReader is;
String line;
// Declare an output stream to client
DataOutputStream os;
String thr = Integer.toString(threadNumber);
// Create a socket object from the ServerSocket to listen and accept
// connections. Open input and output streams
try
{
ObjectOutput output;
output = new ObjectOutputStream( server.getOutputStream() );
is = new BufferedReader( new InputStreamReader(
server.getInputStream()));
//if( (line = is.readLine()) != null )
while( (line = is.readLine()) != null )
{
if(line != null)
{
switch(rules(line)){
case "playertable":
output.writeObject( positions );
break;
case "gamesettings":
output.writeObject( gameSettings );
break;
case "servernumber":
StringReturnSerial string = new StringReturnSerial();
string.s = Integer.toString(threadNumber);
output.writeObject(string);
break;
default:
System.out.println("line didnt select anything");
break;
}
}output.flush();
}
// Comment out/remove the stream and socket closes if server is to remain live.
is.close();
}
catch (IOException e)
{
System.out.println(e + "Error B");
}
}
public TCPserver(int tNumber)
{
threadNumber = tNumber;
}
private synchronized void changeArray(int row, int col, String value)
{
positions.playersArray[row][col] = value;
}
private synchronized String readArray(int row, int col)
{
return positions.playersArray[row][col];
}
private String rules(String lineIn)
{
try {
String[] splitArray = lineIn.split("\\s+");
switch(splitArray[0])
{
case "SIGNIN":
positions.playersArray[threadNumber][0] = splitArray[1];
positions.playersArray[threadNumber][4] = "normal";
positions.playersArray[threadNumber][amountOfPlayerInfoHeld-1] = "connected";
addPlayer();
gameSettings.gameStartTime = System.currentTimeMillis() + 10000;
return "gamesettings";
case "ok":
// just for reply, do nothing response heard "ok"
break;
case "MATCHMAKE":
positions.playersArray[threadNumber][amountOfPlayerInfoHeld -1] = "matchmake";
gameSettings.gameState = "matchmake";
return "playertable";
case "READY":
positions.playersArray[threadNumber][amountOfPlayerInfoHeld -1] = "ready";
return "gamesettings";
case "REQUESTSTART":
boolean goAhead = true;
for(int i = 0 ; i < gameSettings.numberOfConnectedPlayers; i++)
{
if(positions.playersArray[i][amountOfPlayerInfoHeld-1] != "ready")
{
goAhead = false;
}
}
if(goAhead)
{
long start = System.currentTimeMillis( );
start = start + 10000;
gameSettings.gameStartTime = start;
}
return "gamesettings";
case "GETPOS":
return "playertable";
case "UPDATEPOS":
//heres where to notice crashes and check for wins etc...
positions.playersArray[threadNumber][1] = splitArray[1];
positions.playersArray[threadNumber][2] = splitArray[2];
positions.playersArray[threadNumber][3] = splitArray[3];
positions.playersArray[threadNumber][4] = splitArray[4];
return "playertable";
case "GETSETTINGS":
return "gamesettings";
/*case "SENDSETTINGS":
// updates settings
for (int i = 1; i < splitArray.length; i++){
switch(i){
case 1:
gameSettings.gameState = splitArray[i];
break;
case 2:
gameSettings.winningNumberOfLaps = Integer.parseInt(splitArray[i]);
break;
case 3:
gameSettings.winString = splitArray[i];
break;
case 4:
gameSettings.gameStartTime = Long.parseLong(splitArray[i]);
break;
case 5:
gameSettings.numberOfConnectedPlayers = Integer.parseInt(splitArray[i]);
break;
}
}
returnString = "gamesettings";
break;
*/
case "GETSERVERNUMBER":
return "servernumber";
case "PLAYING":
gameSettings.gameState = "playing";
break;
case "SERVERPLAYERSTATEUPDATE":
int crashed = 0;
positions.playersArray[Integer.parseInt(splitArray[1])][5] = splitArray[2];
for(int i = 0; i < gameSettings.numberOfConnectedPlayers;){
//takes into account possibility of people leaving game
if(positions.playersArray[i][5] != null){
if(positions.playersArray[i][5] == "explode"){
crashed++;
}
}
}
if(crashed == gameSettings.numberOfConnectedPlayers)
gameSettings.gameState = "explode";
return "gamesettings";
default:
System.err.println("Rule Not Found: " + splitArray[0]);
break;
}
} catch (PatternSyntaxException ex) {
System.err.println("error C: " + ex);
}
return null;
}
public synchronized void addPlayer()
{
gameSettings.numberOfConnectedPlayers++;
}
public synchronized int getNumberOfPlayers()
{
return gameSettings.numberOfConnectedPlayers;
}
public synchronized void removePlayer()
{
gameSettings.numberOfConnectedPlayers--;
}
}
前もってありがとう ジョン・ハリス