I have a little problem with reading and writing to Sockets in my Server/Client Java application. Server have connection to database. I want to send an object "Employee" consist User Data (Name, Surname, Password) to Server, then Server look up to database about this user and resend to Client information - positive (1) or negative (-1).
First, when I want to send an object Employee, I've got :
"java.net.SocketException: Software caused connection abort: socket write error"
I have my Firewall turned off.
Second, when I want to send and receive just int through writeInt - readInt method for test, I can't to read anything on Server.
What's the problem? Please help.
Code Server:
class ClientCommunication implements Runnable {
private Socket incoming;
public ClientCommunication(Socket clientSocket) {
incoming = clientSocket;
}
public void run() {
try {
synchronized (this) {
try {
serverObjectOutput = new ObjectOutputStream(
incoming.getOutputStream());
serverObjectInput = new ObjectInputStream(
incoming.getInputStream());
} finally {
incoming.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
synchronized(this) {
while (true) {
try{
int operation = serverObjectInput.readInt();
switch(operation) {
case 1:
Employee employee = (Employee) serverObjectInput.readObject();
String SelectUserDataSQL = "SELECT COUNT(*) AS COUNT FROM pracownik where Imie = ? AND Nazwisko = ? AND Haslo = ?";
PreparedStatement CheckEmployeeLogin;
CheckEmployeeLogin = conn.prepareStatement(SelectUserDataSQL);
CheckEmployeeLogin.setString(1, employee.getFirstName());
CheckEmployeeLogin.setString(2, employee.getLastName());
CheckEmployeeLogin.setString(3, new String(employee.getPassword()));
ResultSet resultSQL = CheckEmployeeLogin.executeQuery();
if (resultSQL.next())
if (resultSQL.getInt("COUNT") == 0)
serverObjectOutput.writeInt(1);
else serverObjectOutput.writeInt(-1);
break;
}
} catch(IOException | ClassNotFoundException | SQLException ex)
{
}
}
}
}
}
class ServerStart implements Runnable {
private int portNumber;
public ServerStart(int portNumber) {
this.portNumber = portNumber;
}
public void run() {
try {
conn = getConnection();
stat = conn.createStatement();
} catch (SQLException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
serverSocket = new ServerSocket(portNumber);
} catch (IOException e) {
e.printStackTrace();
}
try {
while (true) {
Socket incoming = serverSocket.accept();
clientSockets.add(incoming);
Runnable r = new ClientCommunication(incoming);
Thread t = new Thread(r);
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Code Client:
public void actionPerformed(ActionEvent e) {
if (isConnected == false) {
String ServerIP = ip.getText().trim();
int ServerPort = Integer
.parseInt(port.getText().trim());
try {
ClientSocket = new Socket(ServerIP, ServerPort);
clientObjectInput = new ObjectInputStream(
ClientSocket.getInputStream());
clientObjectOutput = new ObjectOutputStream(
ClientSocket.getOutputStream());
isConnected = true;
} catch (IOException ex) {
}
synchronized (this) {
try {
ClientLoginFrame login = new ClientLoginFrame();
Employee employee = login.getEmployee();
clientObjectOutput.writeObject(employee);
int result = clientObjectInput.readInt();
if(result == 1)
{
// DO SOMETHING
}
else {
ClientSocket.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
});
}
add an ex.printStackTrace() to see what is happening in your
catch(IOException | ClassNotFoundException | SQLException ex)
Server side, on your ClientCommunication class: it seems you are closing the socket before entering the while loop. So the socket is already closed and cannot send/receive messages. You should NOT call incoming.close() there, but at the end of your run() method.
Related
I have to create a simple rotating proxy application where 100 requests get evenly distributed to 10 devices. I've got the following structure:
WebServer with a Java-SocketServer running. All Android devices are connected to this Socket-Server to be able to know which devices are currently online and for determining which device should be used for the next request.
10 Android devices in different networks. They are connected to the Socket Server and are waiting for requests that should be forwarded to the remote address and then sent back to the SocketServer.
In easy words: I basically have to create an application similar like Honeygain, Peer2Profit or IPRoyal Pawns so that I can later do requests like this:
//Use "-x" to set Proxy-IP and Proxy-Port
curl -x ANDROID_DEVICE_IP:PORT -L https://www.google.com
I managed to have an always running proxy service in an Android application. It basically looks like this and just forwards HTTP-Requests from Port 1440 to the desired remote address and then sends the response back to the original client. The Proxy basically works fine.
public class ProxyServerThread extends Thread {
public static void main(String[] args) {
(new ProxyServerThread()).run();
}
public ProxyServerThread() {
super("Server Thread");
}
#Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(1440)) {
Socket socket;
try {
while ((socket = serverSocket.accept()) != null) {
(new Handler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
return;
}
}
public static class Handler extends Thread {
public static final Pattern CONNECT_PATTERN = Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])", Pattern.CASE_INSENSITIVE);
private final Socket clientSocket;
private boolean previousWasR = false;
public Handler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
String request = readLine(clientSocket);
System.out.println(request);
Matcher matcher = CONNECT_PATTERN.matcher(request);
if (matcher.matches()) {
String header;
do {
header = readLine(clientSocket);
} while (!"".equals(header));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(clientSocket.getOutputStream(), "ISO-8859-1");
final Socket forwardSocket;
try {
forwardSocket = new Socket(matcher.group(1), Integer.parseInt(matcher.group(2)));
System.out.println(forwardSocket);
} catch (IOException | NumberFormatException e) {
e.printStackTrace(); // TODO: implement catch
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 502 Bad Gateway\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
return;
}
try {
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 200 Connection established\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
Thread remoteToClient = new Thread() {
#Override
public void run() {
forwardData(forwardSocket, clientSocket);
}
};
remoteToClient.start();
try {
if (previousWasR) {
int read = clientSocket.getInputStream().read();
if (read != -1) {
if (read != '\n') {
forwardSocket.getOutputStream().write(read);
}
forwardData(clientSocket, forwardSocket);
} else {
if (!forwardSocket.isOutputShutdown()) {
forwardSocket.shutdownOutput();
}
if (!clientSocket.isInputShutdown()) {
clientSocket.shutdownInput();
}
}
} else {
forwardData(clientSocket, forwardSocket);
}
} finally {
try {
remoteToClient.join();
} catch (InterruptedException e) {
e.printStackTrace(); // TODO: implement catch
}
}
} finally {
forwardSocket.close();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
}
private static void forwardData(Socket inputSocket, Socket outputSocket) {
try {
InputStream inputStream = inputSocket.getInputStream();
try {
OutputStream outputStream = outputSocket.getOutputStream();
try {
byte[] buffer = new byte[4096];
int read;
do {
read = inputStream.read(buffer);
if (read > 0) {
outputStream.write(buffer, 0, read);
if (inputStream.available() < 1) {
outputStream.flush();
}
}
} while (read >= 0);
} finally {
if (!outputSocket.isOutputShutdown()) {
outputSocket.shutdownOutput();
}
}
} finally {
if (!inputSocket.isInputShutdown()) {
inputSocket.shutdownInput();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
private String readLine(Socket socket) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int next;
readerLoop:
while ((next = socket.getInputStream().read()) != -1) {
if (previousWasR && next == '\n') {
previousWasR = false;
continue;
}
previousWasR = false;
switch (next) {
case '\r':
previousWasR = true;
break readerLoop;
case '\n':
break readerLoop;
default:
byteArrayOutputStream.write(next);
break;
}
}
return byteArrayOutputStream.toString("ISO-8859-1");
}
}
}
Here comes the Problem:
Everything works fine but only on the local network. I cannot manage to get this to work without port forwarding. Since all devices are on their mobile cellular data I need a way to be able to connect to the device anyway.
How do the mentioned apps manage to connect to the devices?
So I have a multithreaded server that works just fine in the IntelliJ IDE.
The project is a gradle project. Whenever a new client connects to the server, the following is started in a new thread (Class ClientHandler):
#Override
public void run() {
planetNames.addAll(Arrays.asList(names));
while(clientRunning) {
// ==================== LOGIN ====================
try {
this.username = receive.readLine().replace("[LOGIN]:", "");
if (serverServiceCommunicator.isLoggedIn(username)) {
send.println(false);
} else {
send.println(true);
// ==================== NEW GAME ====================
try {
this.user = serverServiceCommunicator.getUserService().getUser(username);
if (user.isFirstGame()) {
send.println("[NEW-GAME]");
// ==================== Overworld Creation ====================
int difficulty = Integer.parseInt(receive.readLine());
this.seed = UUID.randomUUID().hashCode();
Overworld overworld = generateOverworld(this.seed, username, difficulty);
overworldDAO.persist(overworld);
user.setOverworld(overworld);
//====================== Ship Creation ==================
ShipType shipType = (ShipType) receiveObject.readObject();
Ship ship = generateShip(shipType, username, overworld.getStartPlanet());
for (Room r : ship.getSystems()){
if (r.isSystem() && ((System) r).getEnergy()==0){
((System) r).setDisabled(true);
}
}
shipDAO.persist(ship);
user.setUserShip(ship);
Ship userShip = user.getUserShip();
Planet startPlanet = overworld.getStartPlanet();
List<Ship> startPlanetShips = startPlanet.getShips();
startPlanetShips.add(userShip);
startPlanet.setShips(startPlanetShips);
userShip.setPlanet(startPlanet);
//=======================================================
user.setFirstGame(false);
}
// ==================== UPDATE LOGIN ====================
user.setLoggedIn(true);
serverServiceCommunicator.getUserService().updateUser(user);
// ==================== FETCH SHIP ====================
try {
send.println("[FETCH-SHIP]");
sendObject.writeObject(this.serverServiceCommunicator.getClientShip(username));
} catch (Exception f) {
f.printStackTrace();
send.println("[EXCEPTION]:[FETCH-SHIP]:[USERNAME]:" + username);
Server.getInstance().killServer();
throw new IllegalArgumentException(f.getMessage());
}
// ==================== FETCH MAP ====================
try {
send.println("[FETCH-MAP]");
sendObject.writeObject(this.serverServiceCommunicator.getClientMap(username));
} catch (Exception f) {
f.printStackTrace();
send.println("[EXCEPTION]:[FETCH-MAP]:[USERNAME]:" + username);
Server.getInstance().killServer();
throw new IllegalArgumentException(f.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
send.println("[EXCEPTION]:[NEW-GAME]:[USERNAME]:" + username);
}
gameActive = true;
// ===== Add to connected clients =====
this.serverServiceCommunicator.getPvpClients().add(username);
// ==================== RUNNING ====================
while (gameActive) {
if (!clientSocket.getInetAddress().isReachable(2000)) {
RequestObject requestObject = new RequestObject();
requestObject.setRequestType(RequestType.LOGOUT);
requestObject.setUsername(username);
this.serverServiceCommunicator.getResponse(requestObject);
java.lang.System.out.println("[Client-Disconnected]:[Auto-Logout]");
} else {
RequestObject request = (RequestObject) receiveObject.readObject();
sendObject.flush();
sendObject.writeObject(this.serverServiceCommunicator.getResponse(request));
if (request.getRequestType() == RequestType.LOGOUT) {
gameActive = false;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
// Socket will be closed thanks to exception, therefor cannot send more data
// Thread will terminate with socket exception
try {
serverServiceCommunicator.logoutAfterException(username);
clientSocket.close();
Server.getInstance().killServer();
} catch (Exception f) {
f.printStackTrace();
}
}
}
}
ClientHandler Constructor:
public ClientHandler(Socket clientSocket, Server server) throws IllegalArgumentException {
this.clientSocket = clientSocket;
this.server = server;
try {
sendObject = new ObjectOutputStream(clientSocket.getOutputStream());
send = new PrintWriter(clientSocket.getOutputStream(), true);
receiveObject = new ObjectInputStream(clientSocket.getInputStream());
receive = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
serverServiceCommunicator = ServerServiceCommunicator.getInstance();
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException();
}
}
Server run (Class Server):
public void run(){
synchronized (this){
this.serverThread = Thread.currentThread();
}
bindPort(this.port);
System.out.println("Server initialized on " + serverSocket.getInetAddress().getHostAddress() + ":" + this.port + ", listening for connections...");
while (isRunning()){
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(0);
System.out.println("Accepted new connection from "+ clientSocket.getInetAddress().getHostAddress());
}
catch (Exception e){
e.printStackTrace();
}
Server server = this;
new Thread(
new ClientHandler(clientSocket,server)
).start();
}
}
Client side: (Login only requires username, as it is a local multiplayer game)
public boolean login(String username, ShipType shipType, int difficulty) throws IllegalArgumentException {
try {
// ==================== LOG-IN ====================
send.println("[LOGIN]:" + username);
String received = receive.readLine();
// ==================== EXCEPTION ====================
if (received.contains("[EXCEPTION]:[LOGIN]")){
System.out.println("<CLIENT>:[EXCEPTION DURING LOGIN! TERMINATING...]");
throw new IllegalArgumentException();
}
// ==================== SUCCESSFUL LOGIN ====================
else if (received.equals("true")){
System.out.println("<CLIENT>:[LOGIN SUCCESSFUL]:[USERNAME]:" + username);
received = receive.readLine();
// ==================== NEW GAME ====================
if (received.equals("[NEW-GAME]")){
System.out.println("<CLIENT>:[NEW-GAME]:[USERNAME]:"+username+":[SHIP-TYPE]:"+shipType+":[DIFFICULTY]:"+difficulty);
send.println(difficulty);
sendObject.writeObject(shipType);
received = receive.readLine();
}
// ==================== FETCH SHIP ====================
if (received.equals("[FETCH-SHIP]")){
System.out.println("<CLIENT>:[FETCH-SHIP]:[USERNAME]:"+username);
try {
this.myShip = (Ship) receiveObject.readObject();
System.out.println("<CLIENT>:[RECEIVED-SHIP]:[USERNAME]:"+username+":[SHIP-ID]:"+myShip.getId());
}
catch (Exception f){
f.printStackTrace();
System.out.println("<CLIENT>:[EXCEPTION]:[FETCH-SHIP]:[USERNAME]:"+username);
throw new IllegalArgumentException();
}
received = receive.readLine();
}
// ==================== FETCH MAP ====================
if (received.equals("[FETCH-MAP]")){
try {
this.overworld = (Overworld) receiveObject.readObject();
System.out.println("<CLIENT>:[RECEIVED-MAP]:[USERNAME]:"+username+":[MAP-ID]:"+overworld.getId());
}
catch (Exception f){
f.printStackTrace();
System.out.println("<CLIENT>:[EXCEPTION]:[FETCH-MAP]:[USERNAME]:"+username);
throw new IllegalArgumentException();
}
}
return true;
}
// ==================== FAILED LOGIN ====================
else {
return false;
}
}
catch (Exception e){
e.printStackTrace();
try {
socket.close();
}
catch (Exception f){
f.printStackTrace();
}
throw new IllegalArgumentException();
}
}
Client Constructor:
public Client(#NonNull String ipAddress, #NonNull int port) throws IllegalArgumentException {
try {
socket = new Socket();
socket.connect(new InetSocketAddress(ipAddress,port),0);
send = new PrintWriter(socket.getOutputStream(), true);
sendObject = new ObjectOutputStream(socket.getOutputStream());
receive = new BufferedReader(new InputStreamReader(socket.getInputStream()));
receiveObject = new ObjectInputStream(socket.getInputStream());
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("<CLIENT>:[Couldn't initialize connection to server]");
}
}
As seen above I have tried adding a dozen flush() calls to prevent my problem.
The game runs just fine the first time. But if during a login stage there is an exception, due to which the game crashes, upon restarting the jar I get all kinds of exceptions, from OptionalDataExceptions to StreamCorruptedExceptions with different typecodes (Typecode 00 for instance).
The weird thing is, that this only happens with the generated Jar file. In the IDE I can rerun the application dozens of time without errors, even after the exception is thrown. To be able to run the jar again, I need to delete the database file, clear my temp folder and force exit the Jar through task manager.
I believe this is due to data that has been sent but has not been received by the client, so I looked into ways of flushing all socket data before using it, however I have not found anything that helps.
The game is created using LibGDX, the way of storing the data is using Hibernate with an H2 Database (this is obviously bad because of performance but is a requirement).
Any help is much appreciated :]
Turns out having 2 objects written and read from the other end caused the object streams to get corrupted. Fixed it by adding a send/receive before sending the other object. (But why though? Its a TCP socket not a UDP one)
First some Information regarding my Setup.
I have a S8 Cellphone, where i run this App, based upon the AR-Devkit demo from Google.
public void closeSocket(DatagramSocket socket) {
if (socket != null && socket.isConnected() ) {
while (!socket.isConnected()) {
socket.disconnect();
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
if (socket != null && !socket.isClosed()) {
socket.close();
while (!socket.isClosed()) {
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
}
public DatagramSocket createSocket(InetAddress ipAddress, int port) {
try {
DatagramSocket socket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress(ipAddress, port);
socket.setReuseAddress(true);
socket.bind(address);
return socket;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public DatagramSocket getBroadcastListenerSocket() throws IOException {
InetSocketAddress anyAdress = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 9000);
DatagramSocket socket = new DatagramSocket(null);
socket.setSoTimeout(30);
socket.setReuseAddress(true);
socket.bind(anyAdress);
return socket;
}
public DatagramSocket getBroadcastSenderSocket(DatagramSocket oldSocket) {
DatagramSocket socket = null;
try {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
socket = getSocket(oldSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
socket.setBroadcast(true);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
public DatagramSocket getSocket(DatagramSocket oldSocket, InetAddress ipAddress, int port, InetAddress targetAddress) {
if (oldSocket != null ) {
closeSocket(oldSocket);
}
DatagramSocket socket = null;
try {
socket = createSocket(ipAddress, port);
socket.setBroadcast(false);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
if (targetAddress != null)
socket.connect(targetAddress, port);
} catch (SocketException e) {
e.printStackTrace();
}
return socket;
}
public class DatagramReciever extends Thread {
private String datagramToSend = "";
private boolean newDatagramToSend = false;
private DatagramPacket snd_packet;
DatagramSocket senderSocket = null;
DatagramSocket listenerSocket = null;
private DatagramSocket broadCastListenerSocket;
//Buffer gettters and setters
private int writeBuffer = 0;
private SpringAR.comStates oldState;
int getReadBuffer() {
if (writeBuffer == 1) return 0;
return 1;
}
void switchBuffer() {
recieveByteIndex = 0;
writeBuffer = getReadBuffer();
}
public String dbg_message = "";
//Management Communication Headers
public void kill() {
closeSocket(senderSocket);
closeSocket(listenerSocket);
closeSocket(broadCastListenerSocket);
}
public void run() {
try {
initializeBroadcastConnection();
while (true) {
//Recieving Datagramm
DatagramPacket rcv_packet = new DatagramPacket(rcv_message[writeBuffer], rcv_message[writeBuffer].length);
boolean NewMessageArrived = true;
try {
listenerSocket.receive(rcv_packet);
} catch (SocketTimeoutException e) {
NewMessageArrived = false;
}
//Watchdog
handleWatchDogTimer(State);
//TODO Delete String conversion
if (NewMessageArrived) {
dbg_message = new String(rcv_message[writeBuffer], 0, rcv_packet.getLength(), "US-ASCII");
Log.d(SpringAR.dataDebugLogPrefix, "" + rcv_packet.getAddress().getHostAddress() + ": " + dbg_message.trim() + " of " + rcv_packet.getLength() + "length ");
}
if (validatePackageSender(rcv_packet)) {
connectionStateMachine(rcv_message, rcv_packet);
}
//Sending Datagram
if (newDatagramToSend && hostIpAddress != null) {
//Log.d(SpringAR.protocollDebugLogPrefix, "Server sending: " + datagramToSend);
byte[] snd_message = datagramToSend.getBytes();
try {
snd_packet = packSendPackageByState(snd_message);
assert (snd_packet != null);
senderSocket.send(snd_packet);
newDatagramToSend = false;
} catch (IOException e1) {
e1.printStackTrace();
//causes Caused by: android.system.ErrnoException: sendto failed: EINVAL (Invalid argument)
Log.e(SpringAR.protocollDebugLogPrefix, "Server Error in State: " + State.name());
break;
}
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
private void initializeBroadcastConnection() throws IOException {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
senderSocket = getSocket(null, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
broadCastListenerSocket = getBroadcastListenerSocket();
listenerSocket = broadCastListenerSocket;
Log.d(SpringAR.protocollDebugLogPrefix, "initializeBroadcastConnection completed");
}
// handles management traffic like configurstion files
private void connectionStateMachine(byte[][] payload, DatagramPacket rcv_packet) throws IOException {
//Reset triggered by Host
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveResetHeaderByte) != SpringAR.STRING_NOT_FOUND) {
State = SpringAR.comStates.STATE_resetCommunication;
}
Log.d(SpringAR.protocollDebugLogPrefix, "ConnectionStateMachine: " + State.name());
switch (State) {
case STATE_resetCommunication: {
messageCounter = 0;
listenerSocket = broadCastListenerSocket;
hostIpAddress = comonUtils.getBroadcastAddress(context);
senderSocket = getBroadcastSenderSocket(senderSocket);
setSendToSpringMessage(SpringAR.sendResetHeader);
State = SpringAR.comStates.STATE_broadCastHeader;
return;
}
case STATE_broadCastHeader: {
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveHostReplyHeaderByte) != SpringAR.STRING_NOT_FOUND) {
Log.d(SpringAR.protocollDebugLogPrefix, " Host Reply Header recieved");
//Extract the hostIp
String hostIpAdressAsString = new String(payload[writeBuffer]);
hostIpAdressAsString = hostIpAdressAsString.replace(SpringAR.recieveHostReplyHeader, "").trim();
Log.d(SpringAR.dataDebugLogPrefix, hostIpAdressAsString);
hostIpAddress = InetAddress.getByName(hostIpAdressAsString);
//Set Connection from broadcast to target
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
Log.d(SpringAR.protocollDebugLogPrefix, " New Device Adress " + ARDeviceAddress);
senderSocket = getSocket(senderSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, hostIpAddress);
listenerSocket = senderSocket;
State = SpringAR.comStates.STATE_sendCFG;
return;
}
setSendToSpringMessage(SpringAR.sendBroadcasteHeader);
delayByMs(SpringAR.TIME_OUT_IN_BROADCAST);
return;
}
case STATE_sendCFG: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveCFGHeaderByte )) {
State = SpringAR.comStates.STATE_sendRecieveData;
return;
}
setSendToSpringMessage(SpringAR.formConfigurationMessage());
return;
}
case STATE_sendRecieveData: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveDataHeaderByte)) {
writeRecievedDataToBuffer(payload[writeBuffer], rcv_packet.getLength());
}
break;
}
default:
Log.d(SpringAR.protocollDebugLogPrefix, "Connection State Machine invalid state");
}
}
https://github.com/PicassoCT/arcore-android-sdk/blob/6c9b48a3d520e039cd48bc2af7354ccdec857736/arcore-android-sdk/samples/hello_ar/app/src/main/java/com/google/ar/core/examples/app/common/tcpClient/Server.java
All the testing is happening in a home-WiFi Setup, where the desktop with the host-application is directly attached to the WiFi-Router.
What is working thus far:
The device can broadcast its presence.
The host can broadcast its configuration.
The Device can not communicate from IP to IP on the host. Both sides have fixed IP set.
I can communicate with the App PacketSender with the host-Application, and ruled a failure on its part out.
I also built a smaller debug-loop, to only send udp-packets back and forth, which also worked.
Thank you for your time
Change this line:
socket.setSoTimeout(30);
to
socket.setSoTimeout(1000);
You've got a fairly complex state machine going here, and it's difficult to discern what is happening without having logs to look at. I would summarize your state machine like this:
Broadcast a configuration message
Spend 30ms listening for a response
If no response is received, block for SpringAR.TIME_OF_FRAME_IN_MS (not included in your code; I assume it is 1000ms), and loop back to #1
If a response was received, send a reply directly to the peer, and go to #2
#4 is the step that isn't happening. The likely reason (based on the Wireshark dump) is that it's taking 68ms for ARDevice's response to reach "Host". You only gave it 30ms. There could be a number of reasons it's taking so long, but that's beyond the scope of your question.
My server closes after one clients disconnects,and I can write only one more message then it crashes.I wonder why,since I only close the client socket when it types "EXIT SERVER" .This is the exception it throws:
java.io.EOFException
This is my code :
import java.net.*;
import java.io.*;
public class ServerPeer extends Thread {
Socket _socket;
String username;
public ServerPeer(Socket _socket) {
this._socket = _socket;
}
public void sendMessage(String _username, String _message) throws IOException {
ObjectOutputStream _obj = new ObjectOutputStream(
_socket.getOutputStream());
_obj.writeObject(new Message(_username, _message));
_obj.flush();
}
public synchronized void run() {
try {
ObjectInputStream _ois = new ObjectInputStream(_socket.getInputStream());
Message _message;
while (_socket.isConnected()) {
_message = (Message) _ois.readObject();
String divide = _message.getAll().substring(0, _message.getAll().indexOf(":"));
username = divide;
Server.listofusers.add(username);
for (ServerPeer sp : Server.listofpeers) {
if (_message.getAll().contains("EXIT SERVER")) {
Server.listofpeers.remove(sp);
_socket.close();
}
if (_message instanceof PrivateMessage) {
PrivateMessage privm = (PrivateMessage) _message;
for (ServerPeer sp2 : Server.listofpeers) {
if (sp2.username.equals(privm.getReceiver())) {
sp2.sendMessage(divide, privm.getAll());
String priv = privm.getAll().replaceAll("/w", "");
System.out.println(priv);
break;
}
}
} else {
sp.sendMessage(divide, _message.getAll());
System.out.println(_message.getAll());
}
}
_ois = new ObjectInputStream(_socket.getInputStream());
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Server Class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
static ServerConfig _svconfig = new ServerConfig();
public static ArrayList<ServerPeer> listofpeers = new ArrayList<ServerPeer>();
public static ArrayList<String> listofusers = new ArrayList<String>();
public static int i = 0;
// final static int _mysocket;
public static void main(String[] args) {
try {
final int _mysocket = _svconfig.getPORTNumber();
System.out.println("Wainting for clients.....");
ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
Socket _clientsocket = _serversocket.accept();
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}
_serversocket.close();
} catch (MissingKeyException e) {
e.printStackTrace();
} catch (UnknownKeyException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (BindException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (SocketException e) {
System.out.println("You have been disconnected");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
EDIT:
Exception thrown in the console of the client who disconnects:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2328)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2797)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at ClientPeer.serverEcho(ClientPeer.java:35)
at ClientPeer.run(ClientPeer.java:44)
BUILD STOPPED (total time: 1 minute 26 seconds)
From what I can tell i'd guess your code is incorrect, but it hard to tell without more code.
At first glance it seems that if too many people connect to your server you just shut down the entire server not just those connections.
while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
Socket _clientsocket = _serversocket.accept();
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}
_serversocket.close();
A better approach would be something like the following. If too many users try to connect, just close the users connection.
ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
boolean alive = true;
while (alive) {
try {
//Keep accepting connection request
Socket clientRequest = _serversocket.accept();
//Check if too many user are connected
if (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}else{
//Reject connection if too many connected
clientRequest.close();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
//When server dead close it down
_serversocket.close();
Hope this helps.
Your code must be exiting after the client thread is terminated, create a thread that has the server accept method that starts the client thread, something like this,
/**
*/
private class ServerListener extends Thread
{
/**
*/
public void run()
{
try
{
Socket clientSocket = socket.accept();
System.out.println("client connected => "+clientSocket.getInetAddress().getHostAddress());
ServerListener th = new ServerListener();
th.start();
ClientThread cth = new ClientThread(clientSocket);
cth.start();
clients.add(cth);
return;
}
catch (Exception e)
{
e.printStackTrace();
//Main.getInsatance().println(e);
//Main.getInstance().println("socket disconnected => "+clientSocket.getInetAddress().getHostAddress());
}
}
}
I am pretty new to writing client/server based apps. both server and client classes are kicked off in threads. New to using Object Output/input streams over tcp aswell. Have never had fun with serialization. In my application I am trying to use Object Input/Output Streaming but it looks like opening them is causing my application dies. The funny thing is that if I comment two lines:
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
Connection works nicely and app proceeds to the next panels etc. But I am still not capable of sending any objects throughout the socket. When I literally try to open those streams. It still connects but app get freezed. I 've got two questions:
first: is it better to use serialization
second: if I can use Object streaming, how should I open them? Can I do it inside the server/client thread?
Thanks for Your time
Here is the code of ClientApp:
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
Do you use Serializable interface for the Map object ?
If you still frozen at a step, its maybe because you try to read object (from server or client) and you didn't send it by the other side. While the object is not read it will wait for content.
I dont know how work your server, but you read response twice when oppenentReady is false.
if (inStream.readObject() != null) {
if (inStream.readObject() instanceof Boolean) {
//...
}
}
If this is not the expected behavior, you should store it in local variable.
Once again, this's smt I want to implement(in steps)
1. user choose to open connection(he becomes a server and waits for a client
to connect) - done.
2. second user choose to connect(becomes a client and connects to the
second player(server) - done.
3. Both get message that the connection is established and they are moved
to the next Panel where they do specific operations - done.
4.When anyone of them finishes, I want to tell it to the second guy
(it is represented by a boolean local varable) - here comes the problem.
5. When both have finished, they should be moved to the next Panel where
they play.(before they start playing, Maps that they have set in the previous Panel
should be sent to each other.
Next steps I can handle if Only I knew maybe not how to send those informations
but where to place sending code because it seems to be in the wrong place. Here is the full code of client/server classes:
connecting - is set to true in the other class after pushing the button.
iAmready - is set to true when player finishes setting up the map and should be sent to opponent,
because it triggers a specific operation by setting opponentIsReady to true when obtained.
public class ClientApp implements Runnable
{
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
FileOutputStream out = new FileOutputStream("/tmp/message.ser");
outStream = new ObjectOutputStream(out);
FileInputStream in = new FileInputStream("/tmp/message.ser");
inStream = new ObjectInputStream(in);
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}
inStream.close();
outStream.close();
in.close();
out.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public class ServerApp implements Runnable
{
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
public ServerApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e) {}
try
{
if (connecting)
{
hostServer = new ServerSocket(port);
socket = hostServer.accept();
connected = true;
connecting = false;
JOptionPane.showMessageDialog(null, "Connection Established!");
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
connected = connecting = false;
}
catch (IOException e)
{
connected = connecting = false;
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected(server)");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
inStream = new ObjectInputStream(socket.getInputStream());
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do servera!");
outStream = new ObjectOutputStream(socket.getOutputStream());
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
As i said before, you can not use readObject() more than once for the same object.
Example,
Use:
Object objectRead=inStream.readObject();
if (objectRead != null) {
if (objectRead instanceof Boolean) {
opponentIsReady = Boolean.valueOf(objectRead);
System.out.println(opponentIsReady);
} else if (objectRead instanceof Map) {
mapToGet = (Map) objectRead;
}
}
Instead of:
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
I think you didn't understand how it works:
When the client/server connection is etablished you can use Threads to read or write objects.
I give you code that you can test to understand how it works:
ServerApp:
public class ServerApp implements Runnable {
public static int port = 1000;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
private boolean connected = false;
public ServerApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
// Server initialization side
try {
hostServer = new ServerSocket(port);
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
// Accept will wait until a client try to connect
socket = hostServer.accept();
JOptionPane.showMessageDialog(null, "Connection Established!");
// Init streams when connection is etablished
inStream = new ObjectInputStream(socket.getInputStream());
outStream = new ObjectOutputStream(socket.getOutputStream());
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected = true;
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
int x = 0;
// The loop is made to send/receive all messages
while (connected) {
try {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
Object o = String.format("I send you a message (%s)", x++);
outStream.writeObject(o);
Object response = inStream.readObject();
System.out.println("Response: " + response);
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ClientApp:
public class ClientApp implements Runnable {
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = true;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
try {
// Client initialization side
socket = new Socket(hostIP, port);
// If the socket connection succeed it pass, else execption is thrown
JOptionPane.showMessageDialog(null, "Connection Established!");
// Initialize streams
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected=true;
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
}
// The loop will receive server message and send response
while (connected) {
try {
Object serverMessage = inStream.readObject();
System.out.println("Server sent: " + serverMessage);
Object myResponse = String.format("I received %s", serverMessage);
outStream.writeObject(myResponse);
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (connected) {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (connected) {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}