I want to transfer objects (AssignmentListener) from one Java Server to 5 Java Clients.
Therefore I wrote a method to send out the message:
private void sendMessage(AssignmentListener listener, int[] subpartitionIndices){
boolean success = false;
int failCount = 0;
// retry for the case of failure
while(!success && failCount < 10) {
try {
// get the stored socket & stream if stored
if(listener.getSocket() == null) {
if (localMode) {
listener.setSocket(new Socket("localhost", listener.getPort()));
} else {
listener.setSocket(new Socket(listener.getIp(), listener.getPort()));
}
listener.setOutputStream(new ObjectOutputStream(listener.getSocket().getOutputStream()));
}
AssignmentListenerMessage assignmentListenerMessage = new AssignmentListenerMessage(subpartitionIndices);
System.out.println("Sending " + assignmentListenerMessage);
listener.getOutputStream().writeObject(assignmentListenerMessage);
listener.getOutputStream().flush();
success = true;
} catch (IOException se) {
se.printStackTrace();
System.err.println("Failed to forward " + Arrays.toString(subpartitionIndices) + " to " + listener);
failCount++;
}
}
}
On the client side, I have the following:
public void run() {
String mode = "remote";
if(localMode) mode = "local";
// we need to register this listener at at the OverpartitioningManager
if(register(isLocalRequest)) System.out.println("Registered AssignmentListenerServer for index "+subpartitionIndex+" at ForwardingServer - "+mode);
running = true;
while (running) {
try {
socket = serverSocket.accept();
// Pass the socket to the RequestHandler thread for processing
RequestHandler requestHandler = new RequestHandler( socket );
requestHandler.start();
} catch (SocketException se) {
se.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class RequestHandler extends Thread {
private Socket socket;
RequestHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
System.out.println("Received a connection");
// Get input and output streams
inStream = new ObjectInputStream(socket.getInputStream());
//outStream = new DataOutputStream(socket.getOutputStream());
AssignmentListenerMessage incomingMessage = null;
while(socket.isBound()) {
try {
incomingMessage = (AssignmentListenerMessage) inStream.readObject();
}catch (StreamCorruptedException sce){
System.out.println("Failed to read AssignmentMessage from Stream, but will try again... (no ack)");
sce.printStackTrace();
continue;
}
// do stuff with the message
}
// Close our connection
inStream.close();
socket.close();
System.out.println("Connection closed");
} catch (Exception e) {
e.printStackTrace();
}
}
}
This works multiple times, but at one point I get the following exception:
java.io.StreamCorruptedException: invalid type code: 00
Does anyone have an idea or any other performance improvement for what I'm doing?
Thanks.
Related
public class NewClass {
ServerSocket myServerSocket;
boolean ServerOn = true;
public NewClass() {
try {
myServerSocket = new ServerSocket(8888);
} catch (IOException ioe) {
System.out.println("Could not create server socket on port 8888. Quitting.");
System.exit(-1);
}
while (ServerOn) {
try {
Socket clientSocket = myServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
cliThread.start();
} catch (IOException ioe) {
System.out.println("Exception found on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
try {
myServerSocket.close();
System.out.println("Server Stopped");
} catch (Exception ioe) {
System.out.println("Error Found stopping server socket");
System.exit(-1);
}
}
public static void main(String[] args) {
new NewClass();
}
class ClientServiceThread extends Thread {
Socket myClientSocket;
boolean m_bRunThread = true;
public ClientServiceThread() {
super();
}
ClientServiceThread(Socket s) {
myClientSocket = s;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
System.out.println(
"Accepted Client Address - " + myClientSocket.getInetAddress().getHostName());
try {
in = new BufferedReader(new InputStreamReader(myClientSocket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(myClientSocket.getOutputStream()));
while (m_bRunThread) {
String clientCommand = in.readLine();
if (clientCommand != null) {
System.out.println("Client Says :" + clientCommand);
}
if (!ServerOn) {
System.out.print("Server has already stopped");
out.println("Server has already stopped");
out.flush();
m_bRunThread = false;
}
if (clientCommand.equalsIgnoreCase("quit")) {
m_bRunThread = false;
System.out.print("Stopping client thread for client : ");
} else if (clientCommand.equalsIgnoreCase("end")) {
m_bRunThread = false;
System.out.print("Stopping client thread for client : ");
ServerOn = false;
} else {
out.println("Server Says : " + clientCommand);
out.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
out.close();
myClientSocket.close();
System.out.println("...Stopped");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
Client Code
public class Client {
public static void main(String[] args) throws IOException {
Socket s = new Socket(InetAddress.getLocalHost(), 8888);
PrintWriter out =new PrintWriter(s.getOutputStream(), true);
out.print("KKKKKKKKKKKKK \r\n");
out.flush();
out.close();
}
The purpose of the above code is to create server socket and client socket to pass data between server and client.When the client sends the data to server .server grab the message and print it on the screen but with following exception.The pop up from the String clientCommand = in.readLine(); line which appeared on server code.
java.net.SocketException: Connection reset
Your code is invalid. Your server code relies on the client implementing the protocol correctly, which this client doesn't. Bad habit. Defensive coding is required. If clientCommand == null you must exit this read loop and close the socket. Your present code will attempt to write to the closed connection, which produces exactly this exception ... later.
I have a multithreaded tcp server, that handles multiple clients.
Each client has its thread on the serverside that keeps the socket connection.
Everything theoretically works fine for many minutes, but at rare occasions, while having multiple clients connected, the following happens:
One of the clients sends a tcp packet to the server and the serverside read times out. I have found many questions, that tackle read timeouts on the clientside, but in my case, this never happens. In my case, the server times out on a read when receiving a packet from a client.
My question is, why and how can this happen and what can I do to handle this problem?
here is my server listener:
public class GameServerTCP extends Thread {
//TCP
private ServerSocket serverSocket;
public Server server;
public int amountOfTCPConnections = 0;
ClassLoader classLoader = getClass().getClassLoader();
File myFile = new File(classLoader.getResource("Sprites/sprite_sheet.png").getFile());
public GameServerTCP(Server game) {
this.server = game;
//TCP
try {
serverSocket = new ServerSocket(6336);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(true) {
//TCP
Socket socket = null;
try {
socket = serverSocket.accept();
Toolkit.getDefaultToolkit().beep();
System.out.println(socket.getRemoteSocketAddress() + " has connected to server.");
}
catch (Exception e) {
e.printStackTrace();
}
new TCPConnection(socket, this);
amountOfTCPConnections++;
if (amountOfTCPConnections > 500) {
System.err.println("Too many clients error! (unsolved)");
server.frame.dispatchEvent(new WindowEvent(server.frame, WindowEvent.WINDOW_CLOSING));
}
}
}
}
here is my server thread that hold each single connection:
public class TCPConnection implements Runnable {
Socket socket;
private Thread thread;
private boolean isRunning = false;
public GameServerTCP serverTCP;
private String gamename = "-1";
public String username;
/**
* This is the future!
* Contains an exact imprint of the player of client side.
* Cheats can be detected here.
*/
private PlayerMP playerMP;
String clientSentence;
TCPConnection(Socket socket, GameServerTCP serverTCP) {
this.socket = socket;
this.serverTCP = serverTCP;
isRunning = true;
thread = new Thread(this);
thread.start();
}
public synchronized void closeConnection() {
if (MasterConnections.connectionsTCP.containsKey(getUniqueConnectionIdentifier())) MasterConnections.connectionsTCP.remove(getUniqueConnectionIdentifier());
if (this.username != null && MasterConnections.currentlyLoggedOnAccounts.contains(this.username)) MasterConnections.currentlyLoggedOnAccounts.remove(this.username);
if (this.gamename != null && serverTCP.server.games.containsKey(this.gamename)) {
Level game = serverTCP.server.games.get(this.gamename);
for (String p : game.playersInLevel) {
if (p.equals(getUniqueConnectionIdentifier())) {
game.playersInLevel.remove(p);
System.out.println(this.username + " has been been removed from game " + this.gamename + ".");
}
}
PacketTCP02LeaveGame tellOthersPacket = new PacketTCP02LeaveGame(this.gamename, this.username);
game.writeDataTCPToAllPlayersInThisLevel(tellOthersPacket);
}
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(socket.getRemoteSocketAddress() + " has been disconnected from server.");
this.serverTCP.amountOfTCPConnections--;
this.stop();
}
public String getUniqueConnectionIdentifier() {
return socket.getInetAddress() + ":" + socket.getPort();
}
public String generateUniqueUDPConnectionIdentifier(InetAddress inetAddess, int udpPort) {
System.out.println("uuc created: ");
System.out.println(inetAddess + "/" + udpPort);
return inetAddess + ":" + udpPort;
}
public void run() {
//version check first
PacketTCP00VersionCheck packetVersionCheck = new PacketTCP00VersionCheck(serverTCP.server.getVersion());
if (MasterConnections.connectionsTCP.containsKey(getUniqueConnectionIdentifier())) {
this.closeConnection();
}
else {
MasterConnections.connectionsTCP.put(getUniqueConnectionIdentifier(), this);
packetVersionCheck.writeData(this);
}
BufferedReader inFromClient;
try {
inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e1) {
e1.printStackTrace();
closeConnection();
return;
}
while(isRunning) {
try {
clientSentence = inFromClient.readLine();
if (clientSentence == null) {
inFromClient.close();
closeConnection();
}
else {
System.out.println("tcprec -> " + (new Date(System.currentTimeMillis())) + " -> " + this.username + " -> " + clientSentence);
this.parsePacket(clientSentence.getBytes());
}
}
catch (SocketTimeoutException ste) {
/**
* TODO:
*/
ste.printStackTrace();
System.err.println("YOU CAN DO SOMETHING HERE!!!!!!!");
closeConnection();
}
catch (Exception e) {
e.printStackTrace();
closeConnection();
}
}
}
public void stop() {
isRunning = false;
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
And here is my client:
public class GameClientTCP extends Thread {
public String gamestate = "logged out";
private Game game;
public Socket tcpSocket;
public boolean isRunning = false;
private String serverSentence;
public boolean hasBeenStarted = false;
public int boundUDPPort = -1;
public static String[] characters = new String[5];
public static boolean charactersAreLoaded = false;
private PrintWriter toServer;
public GameClientTCP(Game game, String ipAddress) {
this.game = game;
}
public boolean tryConnect() {
try {
tcpSocket = new Socket();
tcpSocket.connect(new InetSocketAddress(Settings.SERVER_ADDRESS, 6336), 1000);
System.out.println("Just connected to " + tcpSocket.getRemoteSocketAddress());
game.getSocketClientUDP().prepareBeforeStart();
game.getSocketClientUDP().start();
return true;
} catch (UnknownHostException e1) {
try {
tcpSocket.close();
} catch (IOException e) {
GameError.appendToErrorLog(e);
return false;
}
return false;
} catch (IOException e1) {
try {
tcpSocket.close();
} catch (IOException e) {
GameError.appendToErrorLog(e);
return false;
}
GameError.appendToErrorLog(e1);
return false;
}
}
public void run() {
BufferedReader fromServer;
try {
fromServer = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
toServer = new PrintWriter(tcpSocket.getOutputStream(),true);
} catch (IOException e1) {
GameError.appendToErrorLog(e1);
return;
}
while(isRunning) {
try {
serverSentence = fromServer.readLine();
//System.out.println("Received: " + serverSentence);
if (serverSentence != null) this.parsePacket(serverSentence.getBytes());
}
catch(UnknownHostException ex) {
GameError.appendToErrorLog(ex);
}
catch(IOException e){
GameError.appendToErrorLog(e);
}
catch(Exception e) {
GameError.appendToErrorLog(e);
}
}
}
public void sendMessageToServer(String message) {
try {
toServer.println(message);
toServer.flush();
}
catch (Exception e) {
GameError.appendToErrorLog(e);
System.exit(-1);
}
}
}
I hope to find out more about this issue, please help! :)
EDIT: It may be important to say, that while my program is running, it can occur, that there are no tcp packets sent over a longer period of time. The timeout always happens, when i dont send any packets for at least 20 or 30 minutes and then when i send one again, another client times out.
As it turned out, tcp sockets, that are not used longer than a certain amount of time will be kind of destroyed by peers and therefore lose their connection.
I solved my issue, by sending a nearly empty tcp packet every minute to make it clear to all programs and services, that these sockets are alive!
I have one client file clientRPC.java and server file serverRPC.java. Both communicate using TCP protocol and use objectinput and output stream to transfer data.
my client file:
public class clientRPC {
public static void main(String args[]) {
Socket s = null;
try {
int serverPort = 8888;
s = new Socket("localhost", serverPort);// server name is local host
//initializing input and output streams object and referencing them to get input and output
ObjectInputStream in = null;
ObjectOutputStream out = null;
out = new ObjectOutputStream(s.getOutputStream());
in = new ObjectInputStream(s.getInputStream());
MathsTutor mt = new MathsTutor();
out.writeObject(mt);
out.flush();
System.out.println("Welcome to Maths Tutor Service. The available maths exercises are:\n"
+ "Addition: Enter 'A' or 'a'\n"
+ "Subtraction: Enter 'S' or 's'\n"
+ "Multiplication: Enter 'M' or 'm'\n"
+ "Division: Enter 'D' or 'd'\n"
+ "Enter 'Q' or 'q' to quit");
//System.out.println();
MathsTutor mt1 = (MathsTutor) in.readObject();
String response = in.readUTF();
System.out.println(response);
} catch (UnknownHostException e) {
System.out.println("Socket:" + e.getMessage());
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
System.out.println("close:" + e.getMessage());
}
}
}
}
}
and my server file :
public class serverRPC extends Thread {
String request;
String response;
public static void main(String args[]) {
try {
int serverPort = 8888;
ServerSocket listen_socket = new ServerSocket(serverPort);
while (true) {
Socket clientSocket = listen_socket.accept();
Connection c = new Connection(clientSocket);
}
} catch (IOException e) {
System.out.println("Listen socket:" + e.getMessage());
}
public serverRPC(String s) {
request = s;
}
}
class Connection extends Thread {
ObjectInputStream in;
ObjectOutputStream out;
Socket clientSocket;
public Connection(Socket aClientSocket) {
try {
clientSocket = aClientSocket;
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
this.start();
} catch (IOException e) {
System.out.println("Connection:" + e.getMessage());
}
}
public void run() {
try {
MathsTutor mt = (MathsTutor) in.readObject();
InetAddress ip = clientSocket.getInetAddress();
System.out.println("The Received Message from Client at address:/" + ip.getHostAddress());
System.out.println("====================================");
MathsTutor mt1 = new MathsTutor();
out.writeObject(mt1);
while(true) {
// Read from input
String command = in.readUTF();
System.out.println(command);
}
//System.out.println();
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {/*close failed*/
}
}
}
}
The problem is when I run server and then client on cmd, the client side displays the welcome msg and puts cursor on another line for user input but, I can't type anything, the cursor just blinks... I know this might be simple but it has taken already 3 hours for me and I'm stuck in the same thing.
The cursor marked with red keeps blinking but doesn't let me type anything.
You're writing an object with writeObject() and trying to read it with readUTF(). Illogical.
objects written with writeObject() must be read with readObject().
strings written with writeUTF() must be read with readUTF().
primitives written with writeXXX() must be read with readXXX(), for most values of X.
I have a little problem with my Client-Server Application. When I want to connect more than 1 Client and send smth, or I make logout in my Client and try to connect one more time I got Exception:
"java.io.StreamCorruptedException: invalid type code: 04"
What's the problem? Thank's for help.
Server Code:
class ClientCommunication implements Runnable {
private Socket incoming;
public ClientCommunication(Socket clientSocket) {
incoming = clientSocket;
}
public void run() {
try {
synchronized (this) {
serverObjectOutput = new ObjectOutputStream(
incoming.getOutputStream());
serverObjectInput = new ObjectInputStream(
incoming.getInputStream());
}
} catch (IOException e) {
e.printStackTrace();
}
int operation = -1;
synchronized(this) {
while (true) {
try{
if(serverObjectInput.available() > 0){
operation = serverObjectInput.readInt();
switch(operation) {
case 1:
Employee employee = (Employee) serverObjectInput.readObject();
//CHECK LOGGING DATA
// SEND RESULT = 1 OR RESULT = -1
break;
}
}
} catch(IOException | ClassNotFoundException | SQLException ex)
{
ex.printStackTrace();
}
}
}
}
}
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();
Runnable r = new ClientCommunication(incoming);
Thread t = new Thread(r);
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Client Function:
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) {
ex.printStackTrace();
}
synchronized (this) {
try {
ClientLoginFrame login = new ClientLoginFrame();
Employee employee = login.getEmployee();
clientObjectOutput.writeInt(1);
clientObjectOutput.flush();
clientObjectOutput.writeObject(employee);
int result = clientObjectInput.readInt();
if(result == 1)
{
// DO SMTH
}
else {
isConnected = false;
ClientSocket.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
});
I suspect your problem is that you are sharing the singletons serverInputStream and serverOutputStream between connections. This isn't a problem until you have more than one at which point using the same stream in multiple threads at once corrupts the stream (or makes reading it invalid)
I want to connect to a remote server from thread and keep sending strings. If the connection gets refused the thread should keep polling the port until the server is up again. How can I handle this exception and keep my thread fro crashing? The server may not be up for long time but thread should run indefinitely.
public void SendMessage(String message){
try {
socket = new Socket(actuatorAddress, destPort.get());
outToServer = socket.getOutputStream();
out = new DataOutputStream(outToServer);
out.flush();
out.write(message.getBytes());
} catch (IOException ex) {
System.out.println(ex.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
I changed some part of the code as below. For first time called Connect function and then subsequently called Send Message function through thread. The delay added to reconnecting helped reduce time lag recurred due to connecting to non existing server. Still think that there might be a better solution to the basic problem.
public boolean ConnectToActuator() {
try {
if(actuatorAddress.isReachable(2000)){
socket = new Socket();
socket.setPerformancePreferences(1, 2, 0);
socket.setTcpNoDelay(false);
socket.setSendBufferSize(32);
socket.connect(new InetSocketAddress(actuatorAddress, destPort.get()));
outToServer = socket.getOutputStream();
out = new DataOutputStream(outToServer);
connected = true;
disconnectedTimeout = 0;
}
}catch (ConnectException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}catch (IOException ex) {
connected = false;
System.out.println(ex.getMessage());
}
return connected;
}
public boolean SendToActuator(String message) {
if(connected == false){ //socket.isOutputShutdown()
disconnectedTimeout++;
if(disconnectedTimeout>20){
disconnectedTimeout = 0;
ConnectToActuator();
} else {
return connected;
}
}
try {
out.flush();
out.writeBytes(message);
disconnectedTimeout = 0;
connected = true;
} catch (UnknownHostException uhe) {
connected = false;
System.out.println(uhe.getMessage());
} catch (IOException ioe) {
connected = false;
System.out.println(ioe.getMessage());
}
return connected;
}
Given the following constraints in the comments:
Try to send the message to one of the 10 servers.
If none of the servers are available to receive the message, discard the message.
What you actually want to do is:
Iterate through a list of server addresses
Attempt to send a message to each of them
Break out of the loop right away if successful
Catch any errors on connection failure and try the next server
Here's an example class that will run through that scenario.
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class MessageSender {
private static final Integer destPort = 1234;
private static final String[] serverAddresses = {
"address1",
"address2",
"address3" // Etc....
};
public Boolean SendMessage(String message) {
Boolean messageSentSuccessfully = false;
for (String addy : serverAddresses) {
messageSentSuccessfully = SendMessageToServer(addy, message);
if (messageSentSuccessfully) {
break;
}
}
return messageSentSuccessfully;
}
private Boolean SendMessageToServer(String serverAddress, String message) {
Boolean messageSent = false;
try {
Socket dataSocket = new Socket(serverAddress, destPort);
OutputStream outToServer = dataSocket.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.write(message.getBytes());
out.flush();
messageSent = true;
} catch (Exception e) {
System.out.println(e);
}
return messageSent;
}
}
Hope that helps.
Pseudo:
while(true){
if(connect()) DoClientConnectedStuff();
sleep(reconnectTimeout);
};
please try below changes. if your connection refuses it will wait for 2s(2000ms) and then again try to connect with server. if connection being successful it will take outputstream, write data in a while loop and flush the data.
public void createSocketConnection() throws IOException
{
socket = new Socket(actuatorAddress, destPort.get());
if(socket!=null)
{
outToServer = socket.getOutputStream();
out = new DataOutputStream(outToServer);
}
}
public void SendMessage(String message){
boolean isRunning=false;
try
{
createSocketConnection();
isRunning=true;
while(isRunning)
{
out.write(message.getBytes());
out.flush();
}
} catch (java.net.ConnectException conExcp) {
System.out.println(ex.getMessage());
try{
Thread.sleep(2000);
}catch(Exception ee){}
}
catch (IOException ex) {
System.out.println(ex.getMessage());
}
}