Why my Java server close sockets? - java

I have server and client.
My server acepts all connections and returns to client string.
But when I try to send more lines its crashed with
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Unknown Source)
at server.ServerCore.hiMsg(ServerCore.java:67)
at server.ServerCore.run(ServerCore.java:49)
Here is it my Server Code :
package server;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author pisio
*/
public class ServerCore extends Thread {
private LoadSettings loadSettings = LoadSettings.Init();
private int port = loadSettings.getConfigInt("port");
private int max_connections = loadSettings.getConfigInt("max_connections");
private String ipServer = loadSettings.getConfig("ipServer");
private ServerSocket socket;
private Socket connection;
private boolean serverRuning = false;
private int connectedUsers = 0;
private Vector connVector = new Vector();
#Override
public void run() {
try {
socket = new ServerSocket(port, max_connections);
System.out.println("+++\t Server was started at address:" + socket.getLocalSocketAddress() + " with posible max users " + max_connections);
serverRuning = true;
while (serverRuning) {
if (connectedUsers <= max_connections) {
connection = socket.accept();
connection.setKeepAlive(serverRuning);
connVector.add(connection);
connectedUsers = connVector.size();
hiMsg();
hiMsg();
hiMsg();
}
System.out.println("+++\t Last User:" + connVector.get(connVector.size() - 1).toString());
}
} catch (IOException ex) {
// Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void hiMsg() {
try {
Socket c = (Socket) connVector.get(connVector.size() - 1);
PrintWriter out = new PrintWriter(new OutputStreamWriter(c.getOutputStream()));
out.write("Hi user ! Im server ! Your master ! Blow me down\nping: ? PONG ?");
out.close();
} catch (IOException ex) {
Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void stopServer() {
statusServer();
serverRuning = false;
try {
socket.close();
} catch (IOException ex) {
//Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("+++++\t SERVER WAS STOPED !");
// System.exit(port);
}
public void statusServer() {
if (serverRuning) {
System.out.println("Server running at port:" + port + " with connected users :" + connectedUsers + "/" + max_connections);
} else {
System.out.println("Server IS NOT RUNNING!");
}
}
}
And Here is it my client code :
package meetingsclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.String;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerConnect {
private static ServerConnect sc = null;
private Socket socket = null;
private ServerConnect() {
try {
socket = new Socket("localhost", 8080);
sendHiMsg();
} catch (Exception ex) {
Logger.getLogger(ServerConnect.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void sendHiMsg() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Input:" + in.readLine());
}
public static ServerConnect Init() {
if (sc == null) {
sc = new ServerConnect();
}
return ServerConnect.sc;
}
}
I readed this topic : Socket Exception: socket is closed but this dotn helped me.
// Sorry for the links , but I cant understand how properly to format my code here.

From the javadoc of getOutputStream() in Socket:
Closing the returned OutputStream will close the associated socket.
Also, closing a PrintWriter (and all other Printers/Writers) close their underlying streams as well. So, you are closing your OutputStream by closing the PrintWriter (in hiMsg()) and then trying to write to the socket, which was closed.
To fix the problem, don't close the PrintWriter. Garbage collection will take care of it for you! But do close the socket when you are done with it.

Related

How do i establish communication between socket threads of server in order to communicate between clients?

so i'm trying to create a chess server for a chess application i wrote in java. The two classes i'm including are the main class that starts my TCPServerThreads and this class itselve.
I am able to connect two clients and for example echo their input back to them, but i have no idea, how to exchange information between these two threads. I am trying to forward Server inputs from one client towards the main class, or directly to the other client, so i can update the chess field on the client.
It's pretty much my first time working with servers, so thanks in advance for you patience.
This is my main class:
package Main;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import TCP.TCPServerThread;
public class Main {
public static final String StopCode = "STOP";
public static final int PORT = 8888;
public static int count = 0;
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
//create Server Socket
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("serverSocket created");
//accept client Sockets
while (count < 2) {
try {
socket = serverSocket.accept();
count ++;
System.out.println("socket Nr " + count + " accepted");
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new TCPServerThread(socket).start();
}
}
}
And this is the TCPServerThread:
package TCP;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import Main.Main;
public class TCPServerThread extends Thread{
Timestamp ts;
private int port = 0;
Socket socket;
public TCPServerThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
InputStream is = null;
BufferedReader br = null;
DataOutputStream os = null;
try {
is = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
os = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
String line;
while (true) {
try {
line = br.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
if(line.equalsIgnoreCase("sp") && this.activeCount() == 3) {
os.writeBytes("1" + "\n\r");
os.flush();
}
os.writeBytes("Echo reply: " + line + "\n\r");
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
Thank you very much! I made the tcp threads implement runnable instead of extend thread. Then i added a ConnectionManager between the main and the TCPThreads which isn't static. This way i can put the manager into the TCPThreads constructor and communicate between its objects.

Java - Multi-Threaded Socket Server, How to check a clients connection to the server?

I am wondering how to check if a client is still connected to a server, like to see if the client has crashed, and if not, to check its ping to the server. Im adding all new clients to an ArrayList and when they crash I want to know how to remove them from the list so that I can keep things clean. Im not sure how to do this with Synchronization or if thats possible. If there is a better way too control my threads any advice is welcomed, thanks.
SERVER CODE:
package Main;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MultiThreadedServer implements Runnable{
private static List<Thread> clients = new ArrayList<Thread>();
Socket cs;
private static ServerSocket ss;
private static int port = 25570;
MultiThreadedServer(Socket cs){
this.cs = cs;
}
public static void main(String args[]) throws Exception{
try{
ss = new ServerSocket(port);
System.out.println("Server Listening");
}catch(IOException e){
System.out.println("Port Taken");
}
while(true){
Socket newClient = ss.accept();
System.out.println(newClient.getInetAddress() + " Has Connected");
Thread client = new Thread(new MultiThreadedServer(newClient));
client.start();
clients.add(client);
System.out.println("Connected Clients: " + clients.size());
}
}
public void run(){
try{
PrintStream ps = new PrintStream(cs.getOutputStream());
ps.println("Welcome Client #" + clients.size());
}catch(IOException e){
System.out.println(e);
}
}
}
CLIENT CODE:
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client{
private static String ip = "127.0.0.1";
private static int port = 25570;
public static void main(){
Socket socket;
BufferedReader reader;
PrintWriter writer;
try {
socket = new Socket(ip,port);
BufferedReader in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
OutputStreamWriter os = new
OutputStreamWriter(socket.getOutputStream());
PrintWriter out = new PrintWriter(os);
System.out.println(in.readLine());
} catch (UnknownHostException e) {
System.out.println("ERROR UNKNOWN");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Could not connect to server!");
e.printStackTrace();
return;
}
}
}

Java socket connection receiving and sending String and Object

I've created a client, a server and an object called CcyData. When the client connects to the server I would like the server the send a "Welcome message" like "Hello, you are client# " + clientNumber. as a String and then send an object CcyData. I've managed to get the sending of the CcyData object to work but when I try to read in the "Welcome message" with
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Welcome message from server: "+ input.readLine());
the client stops working, nothing happens. No error message. Below is my code. How can I solve this?
Server.
package net.something;
import java.io.IOException;
import java.net.ServerSocket;
public class SocketServer {
private ServerSocket serverSocket = null;
private int clientNumber = 0;
public SocketServer() {
}
public void listenSocket () {
int clientNumber = 0;
try{
serverSocket = new ServerSocket(9090);
System.out.println("Server started on port 9090");
} catch(IOException e) {
e.printStackTrace();
}
while (true) {
ClientSocket clientSocket;
try{
clientSocket = new ClientSocket(serverSocket.accept(), serverSocket, clientNumber++);
Thread thread = new Thread(clientSocket);
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Class ClientSocket
package net.something;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ClientSocket implements Runnable {
private Socket clientSocket;
private ServerSocket serverSocket;
private int clientNumber;
public ClientSocket(Socket clientSocket, ServerSocket serverSocket, int clientNumber) {
this.clientSocket = clientSocket;
this.serverSocket = serverSocket;
this.clientNumber = clientNumber;
System.out.println("New connection with client# " + clientNumber + " at " + clientSocket);
}
public void run() {
PrintWriter out;
ObjectOutputStream outObjectStream;
try {
out = new PrintWriter(clientSocket.getOutputStream());
out.println("Hello, you are client# " + clientNumber);
outObjectStream = new ObjectOutputStream(clientSocket.getOutputStream());
CcyData ccyData = new CcyData("EUR", 9.56);
System.out.println("CcyData: " + ccyData.getCcy() + " " + ccyData.getFxRate());
outObjectStream.writeObject(ccyData);
} catch (IOException e) {
e.printStackTrace();
}
}
public void finalize() {
try{
serverSocket.close();
System.out.println("Server socket closed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
package net.something;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.Socket;
public class SocketClient {
private Socket socket = null;
private BufferedReader input;
private ObjectInputStream inObjectStream = null;
public SocketClient() {
}
public void connectToServer() {
try{
socket = new Socket("127.0.0.1", 9090);
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Welcome message from server: "+ input.readLine());
inObjectStream = new ObjectInputStream(socket.getInputStream());
CcyData ccyData = (CcyData) inObjectStream.readObject();
System.out.println(ccyData.getCcy() + " " + ccyData.getFxRate());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
finalize is only called when the JVM garbage collector decides that there are no more references to your thread and disposes it. Thus, you cannot ensure that finalize will be called when your thread has reached the end of its run() method. Try closing the socket in the run method instead!

Stream Corrupted Exception

I'm writing a client/server program using sockets. The client first sends the file name and the server reads the file from hard disk and sends back to the client through socket. Finally the client writes the content into a file. When I run the code a java.io.StreamCorruptedException: invalid stream header error is returned.
Client code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ClientSocket {
private static final String SERVER_IP = "10.8.17.218";
private static final int SERVER_PORT = 5000;
String fileName;
String ip;
Socket socket;
Message msg=null,message=null;
ObjectInputStream in = null;
ObjectOutputStream out = null;
ObjectOutputStream toFile=null;
File destFile;
public ClientSocket(String ipi,String fname){
fileName = fname;
ip=ipi;
msg=new Message(fileName);
destFile=new File("C:\\DestinationDirectory",fileName);
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
System.out.println("Connected to server!");
} catch (Exception ex) {
System.out.println("Error connecting to server: " + ex.getMessage());
}
while(true){
try {
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
out.writeObject(msg);
out.flush();
//get the reply from the server
if (in == null) {
in = new ObjectInputStream(socket.getInputStream());
}
message = (Message) in.readObject();
//System.out.println("Server said: " + message.getMessage());
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
try {
toFile = new ObjectOutputStream(new FileOutputStream(destFile));
toFile.writeObject(message);
System.out.println(message.getMessage());
} catch (IOException ex) {
Logger.getLogger(ClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String[] args) {
ClientSocket cs= new ClientSocket("10.8.17.218","build.sql");
}
}
Server code:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerFile {
private static final int PORT = 5000;
public static void main(String[] args) {
ServerSocket serverSocket = null;
Message message=null,toOut=null;
try {
//Creates a new server socket with the given port number
serverSocket = new ServerSocket(PORT);
} catch (IOException ex) {
System.out.println("Error occured while creating the server socket");
return;
}
Socket socket = null;
try {
//Waits untill a connection is made, and returns that socket
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Error occured while accepting the socket");
return;
}
//Now we have established the a connection with the client
System.out.println("Connection created, client IP: " + socket.getInetAddress());
ObjectInputStream in = null,fromFile=null;
ObjectOutputStream out = null,tempOut=null;
File sourceFile;
FileInputStream from=null;
BufferedInputStream bis;
String name=null;
while(true){
try {
if (in == null) {
in = new ObjectInputStream(socket.getInputStream());
}
message= (Message) in.readObject();
System.out.println("Client said: " + message.getMessage());
name=message.getMessage();
sourceFile=new File("D:\\temp\\",name);
name="D:\\temp\\"+name;
System.out.println(name);
from=new FileInputStream("D:/temp/build.sql");
bis=new BufferedInputStream(from);
fromFile=new ObjectInputStream(bis);
toOut=(Message) fromFile.readObject();
//Send a reply to the client
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
out.writeObject(toOut);
out.flush();
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
}
}
}
You're creating a new ObjectInputStream per transaction in the server, yet you're using a single ObjectOutputStream in the client. You should use exactly one of each at both ends for the life of the socket.

Corrupted inputStream

It errors at the last line in the client code, with the code. java.io.StreamCorruptedException: invalid stream header: 36353137. I haven't done anything to the stream before this point, so I am unsure what could be causing the problem with the ObjectInputStream.
The server class works properly, and follows the behavior I set for it, it is only the client class that is erroring.
I thought the problem at first might be because the stream wasn't being flushed, but flushing it did not fix the issue.
Apart from that, since this error is happening so early in the code, I am at a loss as to what to add to fix it.
Client class -
import java.io.*;
import java.net.*;
public class tcpClient {
int nonce;
Socket requestSocket;
ObjectOutputStream out;
ObjectInputStream in;
String message;
tcpClient(){}
void run()
{
try{
requestSocket = new Socket("localhost", 3223);
System.out.println("Connected to localhost in port 3223");
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
in = new ObjectInputStream(requestSocket.getInputStream());
Server Class -
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.Random;
import java.util.Scanner;
import javax.swing.Timer;
public class TCPMasterServer
implements ActionListener
{
ServerSocket server;
Socket client;
Random random;
Calendar rightNow;
Timer timer;
String ipaddress;
PrintWriter out;
BufferedReader ir;
public TCPMasterServer()
{
this.random = new Random();
this.rightNow = Calendar.getInstance();
try
{
this.server = new ServerSocket(3223);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void listenForConnection()
{
try
{
this.client = this.server.accept();
this.ipaddress = this.client.getInetAddress().getHostAddress();
System.out.println(this.rightNow.getTime() + ": Connected from: " + this.ipaddress);
this.out = new PrintWriter(this.client.getOutputStream(), true);
this.ir = new BufferedReader(new InputStreamReader(this.client.getInputStream()));
communicateWithClient();
}
catch (Exception e)
{
e.printStackTrace();
listenForConnection();
}
}
private void communicateWithClient()
{
this.timer = new Timer(2000, this);
this.timer.setRepeats(false);
this.timer.start();
try
{
int nonce = this.random.nextInt(1000000);
this.out.println(nonce);
System.out.println(this.rightNow.getTime() + ": Send nonce: " + nonce);
String input = this.ir.readLine();
Scanner in = new Scanner(input);
int nonceResponse = in.nextInt();
System.out.print(this.rightNow.getTime() + ": Received number: " + nonceResponse);
if (nonceResponse == nonce + 1)
{
System.out.println("... OK");
this.out.println("SEND_NAME");
System.out.println(this.rightNow.getTime() + ": Request name");
input = this.ir.readLine();
System.out.println(this.rightNow.getTime() + ": Received name: " + input);
this.out.println(input + " ACK");
System.out.println(this.rightNow.getTime() + ": ACK sent");
}
this.client.close();
}
catch (Exception ex)
{
System.out.println(this.rightNow.getTime() + ": Error happened. Giving up");
}
this.timer.stop();
System.out.println();
listenForConnection();
}
public void actionPerformed(ActionEvent evt)
{
try
{
System.out.println("Timer fired.");
this.client.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
TCPMasterServer server = new TCPMasterServer();
server.listenForConnection();
}
}
You're using object streams at the server, but readers and writers at the client. That won't work. If you want to read objects you must write objects.

Categories