I have server and client applications running on my local machine.
Client takes file, changes it and sends to server, then server responds if the file is correct. Client does it multiple times, sending one file at a time.
I send two files from client and on the second file I get Connection reset
Server snippet:
private void initServer() throws IOException {
while (true) {
ServerSocket server = new ServerSocket(55555);
Socket fromclient = server.accept();
InputStream sin = fromclient.getInputStream();
OutputStream sout = fromclient.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
String line = in.readUTF();
if (line.equals("new file")) {
long fileSize = in.readLong();
tempSavedFile = new File("/home/evgeniy/Files/Downloads/temp");
tempSavedFile.createNewFile();
try (FileOutputStream fos = new FileOutputStream(tempSavedFile)) {
int t;
for (int i = 0; i < fileSize; i++) {
t = sin.read();
fos.write(t);
}
}
if (checkPadding(tempSavedFile)) {
out.writeInt(PADDING_OK_RESPONSE);
} else {
out.writeInt(PADDING_ERROR_RESPONSE);
}
out.flush();
}
out.close();
in.close();
sout.close();
sin.close();
fromclient.close();
server.close();
}
}
Client class that calls new thread in for loop
for (byte i = 0; i < 2; i++) {
Callable callable = new FileSender(tempFile);
FutureTask<Integer> ftask = new FutureTask<>(callable);
Thread thread = new Thread(ftask);
thread.start();
int response = 3244;
try {
response = ftask.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
putMessage(String.valueOf(response));
Client Callable thread:
public Integer call() throws Exception {
Socket socket = new Socket(address, serverPort);
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
out.writeUTF("new file");
out.flush();
out.writeLong(file.length);
out.flush();
sout.write(file);
sout.flush();
System.out.println(socket.isConnected());
int response = in.readInt();
System.out.println("--------RESP="+response);
out.close();
in.close();
sin.close();
sout.close();
socket.close();
return response;
}
As you can see I send two files, and get this console output on client app:
true
--------RESP=200
true
ноя 20, 2018 5:16:36 PM com.evgeniy_mh.paddingoracle.FXMLController SendFileToServer
SEVERE: null
java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset
Also, I don't understand why socket is ok, but
int response = in.readInt();
raising Connection reset exception.
Your code creates a new ServerSocket and later closes the created server socket for every single request that it processes. The code does not use the same ServerSocket instance to serve multiple requests.
The connection reset failure appears to be because of this, as when the second request is creating a socket connection with the server, the existing ServerSocket is closed and recreated on the same port leading to the connection being reset. For a start try taking out the ServerSocket creation outside the while loop.
private void initServer() {
try (ServerSocket server = new ServerSocket(5555)) {
while (true) {
Socket fromclient = server.accept();
... // remaining code
fromclient.close();
}
} catch (IOException ioe) {
// handle failures
}
}
The try-with-resources handles the .close() call on the AutoCloseable server socket.
Also, note that the requests would be processed serially on a single thread in your code. Usually the Socket obtained for a connection from the ServerSocket#accept() (or the streams derived from it) is passed to a separate thread for processing unlike your code that processes the requests serially.
Related
im trying to listen on HTTP requests for an website in my application. My application is used to extract some data from the inputstream of Socket1 and forward it to the output stream of another socket2 (the client socket2 which connects to the actual webserver). The webserver should anser (->Inputstream2) and i want to pass it back to outputstream1 of socket1.
The real webserver is getting an request, but im not receiving an answer, in this constellation. I read, that i have to close the output stream of an socket bevor can start to read the inputstream, so I also tried socket.shutdownOutput() but it's still not working.
I would appriciate any help
private static void runHttpListener(Boolean simulate){
try {
ServerSocket server = new ServerSocket(PORT_HTTP_REQUEST);
System.out.println("HTTP listener active on Port "+PORT_HTTP_REQUEST);
boolean keepAlive = true;
while (keepAlive) {
//Empfangen und auslesen
Socket socketReceivingProxy = server.accept();
System.out.println("HTTP-Listener: Accepted client connection");
InputStream proxyInputStream = socketReceivingProxy.getInputStream();
OutputStream proxyOutputStream = socketReceivingProxy.getOutputStream();
//TODO: extract information from stream
//forward
InputStream result = sendHttpRequestToDestination(proxyInputStream, simulate);
result.transferTo(proxyOutputStream);
result.close();
proxyOutputStream.close();
socketReceivingProxy.close();
}
server.close();
System.out.println("HTTP listener closed");
} catch (Exception e) {
e.printStackTrace();
}
My forwarding method is realy simple but it doesn't actually works:
private static InputStream sendHttpRequestToDestination(InputStream incomingRequest, Boolean simulate){
try{
Socket socketForwardingWebapp = new Socket(simulate?URL_WEB_SERVER_SIMULATION:URL_WEB_SERVER,
simulate?PORT_WEB_SERVER_SIMULATION:PORT_WEB_SERVER);
System.out.println("HTTP-Forwarding: Created socket "+socketForwardingWebapp.getInetAddress()+":"+socketForwardingWebapp.getPort());
InputStream webappInputStream = socketForwardingWebapp.getInputStream();
OutputStream outputStream = socketForwardingWebapp.getOutputStream();
if(incomingRequest.available()>0){
System.out.println("Incoming Request can be forwarded");
long bytesTransfered = incomingRequest.transferTo(outputStream);
System.out.print("stream copied");
socketForwardingWebapp.shutdownOutput();
System.out.println("Bytes forwareded: "+bytesTransfered);
}
return webappInputStream;
}catch(Exception exc){
exc.printStackTrace();
}
return null;
}
I solved this problem using Threads. Here is what worked:
private static Thread inputStreamToOutputStream(InputStream inputStream, OutputStream outputStream){
Thread t = new Thread(() -> {
long transferedBytes = 0;
try {
transferedBytes = inputStream.transferTo(outputStream);
inputStream.close();
outputStream.close();
System.out.println("StreamTransformer: Bytes forwareded: "+transferedBytes);
} catch (IOException e) {
System.out.println("StreamTransformer: Error accoured while transforming");
}
});
t.start();
return t;
}
Used this new method like this:
private static Thread sendHttpRequestToDestination(InputStream incomingRequest, OutputStream outgoingAnswer, Boolean simulate){
Thread t = new Thread(){
public void run(){
try{
Socket socketForwardingWebapp = new Socket(simulate?URL_WEB_SERVER_SIMULATION:URL_WEB_SERVER,
simulate?PORT_WEB_SERVER_SIMULATION:PORT_WEB_SERVER);
System.out.println("HTTP-Forwarding: Created socket "+socketForwardingWebapp.getInetAddress()+":"+socketForwardingWebapp.getPort());
InputStream webappInputStream = socketForwardingWebapp.getInputStream();
OutputStream outputStream = socketForwardingWebapp.getOutputStream();
if(incomingRequest.available()>0){
System.out.println("HTTP-Forwarding: Incoming Request can be forwarded");
Thread send = inputStreamToOutputStream(incomingRequest, outputStream);
Thread receive = inputStreamToOutputStream(webappInputStream, outgoingAnswer);
send.join();
System.out.println("HTTP-Forwarding: successfuly sent");
receive.join();
System.out.println("HTTP-Forwarding: successfuly received");
}
socketForwardingWebapp.close();
}catch(Exception exc){
exc.printStackTrace();
}
}
};
t.start();
return t;
}
currently I am trying to send multiple messages from a client to a server and echo them on the server but somehow my message is not arriving at the server until i press CTRL+Z(D) and hit enter.
My loop runs as long as the user does not enter "quit" but altough I write my message to the OutputStream and flush it my message does not show on the Server side as if my Client still reads input.
(I do not want to use BufferedReaders or Threads at the moment it's purely for learning reasons.)
Would be nice if someone could tell me where my mistake/error lies.
Read also the javadocs but still can not find my mistake.
Client.java
public class Client {
//class members
private String msg = null;
private Scanner scn = null;
public Client(String ip, int port) throws IOException {
//Connect to Server
try(Socket socket = new Socket(ip,port))
{
//Initialize class members
scn = new Scanner(System.in); //Init Scanner
msg="";
System.out.println("Enter message:");
//Write to Socket
OutputStream out = socket.getOutputStream();
while(!msg.equals("quit"))
{
msg=scn.nextLine();
out.write(msg.getBytes(), 0, msg.length());
out.flush();
}
}
catch (IOException ex)
{
System.err.println(ex);
}
}
Server.java
public class Server {
//class members
private String msg = null;
public Server(int port) throws IOException {
//Setup ServerSocket.
ServerSocket server = new ServerSocket(port);
System.out.println("SERVER: Launched service.");
//Accept incoming connection requests.
while(true) {
try(Socket connection = server.accept())
{
System.out.println("SERVER: Client connection accepted.");
//Read Input
StringBuilder line = new StringBuilder();
InputStream in = connection.getInputStream();
for(int c=in.read(); c!=-1; c=in.read())
{
line.append((char) c);
}
System.out.println(line);
}
catch (IOException ex)
{
System.out.println("SERVER: Client disconnected!");
}
}
}
sincerely,
rhyleigh
Your server prints nothing until read() returns -1.
read() returns -1 at end of stream.
Over a TCP socket, end of stream is only caused by the peer closing the connection.
Your server's peer, i.e. the client, doesn't close the connection until you type ^Z at the terminal. which causes an unstated exception to be thrown.
Your program is working as designed.
I have this client and server programs.
The client get a command from user, and send it to the server, and the server return the result (output of the command) to the client.
I have 2 classes Command and CommandResult (represents the command and the result), and I'm passing them as json with ObjectInput(/Output)Stream.
This is the code:
Client
Socket socket = new Socket("localhost", 1111);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
while (true) {
//get command from user
Scanner scanner = new Scanner(System.in);
System.out.println("Enter command:");
String cmd = scanner.nextLine();
Command command = new Command(cmd);
//send the command as json
String jsonCommand = new Gson().toJson(command);
out.writeObject(jsonCommand);
out.flush();
//get and print the result
String jsonCommandResult = (String) in.readObject();
CommandResult commandResult = new Gson().fromJson(jsonCommandResult, CommandResult.class);
System.out.println(commandResult.getOutput());
}
Server
ServerSocket serverSocket = new ServerSocket(1111);
Socket socket = serverSocket.accept();
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
while (true) {
//read the command
String cmd = (String) in.readObject();
Command command = new Gson().fromJson(cmd, Command.class);
//run() method will run the command with java Process and return the result
CommandResult commandResult = command.run();
//sent the result back to the client as json
String jsonCommandResult = new Gson().toJson(commandResult);
out.writeObject(jsonCommandResult);
out.flush();
}
Now, this is working fine when I have one client.
But if I'm trying to run a second instance of the client program, while the first one is still in the loop, it hangs in the ObjectInputStream constructor. (third line)
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
As I understand from the documentation, the constructor block until the corresponding ObjectOutputStream has been created.
Creates an ObjectInputStream that reads from the specified InputStream.
A serialization stream header is read from the stream and verified.
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
In my case the server has not accept the new client yet, and therefore the ObjectOutputStream has not been created.
Now, what I want is to throw exception if a new client trying to connect while other client is connected to the same port.
But I can't figure it out how to check if the port is now in use before calling this constructor.
As #Kayaman proposed in the comments, I created a Runnable class handles the current client.
Then in the server, I'm looping on serverSocket.accept() and allowing only one client at the time by starting a new thread for the first client, and check whether the current client is finished his communication or not.
Here is the final Server class.
public class Server {
private static final int SERVER_READY = 1;
private static final int SERVER_BUSY = 0;
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
int port = Integer.valueOf(args[0]);
System.out.println(String.format("Starting server on port %s", port));
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server is ready");
Thread clientThread = null;
while (true) {
Socket clientSocket = serverSocket.accept();
OutputStream os = clientSocket.getOutputStream();
if (clientThread != null && clientThread.isAlive()) {
os.write(SERVER_BUSY);
continue;
}
os.write(SERVER_READY);
System.out.println(String.format("Client connected: %s", clientSocket.getInetAddress()));
clientThread = new Thread(new ClientWorker(clientSocket));
clientThread.start();
}
}
public static class ClientWorker implements Runnable {
private final Socket clientSocket;
ClientWorker(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
handleClient();
} catch (Exception e) {
e.printStackTrace();
}
}
private void handleClient() throws IOException, ClassNotFoundException {
try {
ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
while (true) {
System.out.println("Waiting for command..");
String cmd = (String) in.readObject();
System.out.println(String.format("Command received:\n %s", cmd));
if (cmd.equals("exit"))
break;
Command command = new Gson().fromJson(cmd, Command.class);
CommandResult commandResult = command.run();
String jsonCommandResult = new Gson().toJson(commandResult);
System.out.println(String.format("Sending response:\n %s", jsonCommandResult));
out.writeObject(jsonCommandResult);
out.flush();
}
//in case the client connection has closed, we want to end the while loop and accept a new client
} catch (EOFException | SocketException e) {
}
System.out.println("Connection has been closed");
clientSocket.close();
System.out.println("Server is ready");
}
}
}
In the Client class, I check if the Server is ready or not.
Socket socket = new Socket(HOST, PORT);
int status = socket.getInputStream().read();
if (status != SERVER_READY)
throw new Exception(String.format("Failed to connect to server %s:%s, Server is busy", HOST, PORT));
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
....
....
I'm trying to program a Server Client program where the CLIENT will be prompt if the SERVER closes or loses connection. What happens is once I connect the server and the client then disconnects the server it doesn't go to the ConnectException part
example: I opened the Server and Client connects, in the Client it will show that "You are connected to the Server", then if the Server disconnects there should be a "Server is disconnected". and when the Server reopens it will prompt the Client that he's connected to the Server
How can I continuously check if the Server is open or disconnected
here's my code:
SERVER
public class Server
{
private static Socket socket;
public static void main(String[] args)
{
try
{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
//Server is running always. This is done using this while(true) loop
while(true)
{
//Reading the message from the client
socket = serverSocket.accept();
System.out.println("Client has connected!");
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to client.
returnMessage = "Please send a proper number\n";
}
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
CLIENT
public class Client
{
private static Socket socket;
public static void main(String args[])
{
Scanner input=new Scanner(System.in);
try
{
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
System.out.println("Connected to the Server");
}
catch (ConnectException exception)
{
System.out.println("Server is still offline");
}
catch(IOException ex)
{
System.out.println("Server got disconnected");
}
}
}
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
you can do like this
try
{
Socket s = new Socket("address",port);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
or you can simply et connection time out like this socket.setSoTimeout(timeout); to check connectivity
or you can use
socket.getInputStream().read()
makes the thread wait for input as long as the server is connected and therefore makes your program not do anything - except if you get some input and
returns -1 if the client disconnected
or what you can do is structure your code in this way
while(isConnected())
{
// do stuffs here
}
Hi I have the following code to the client - server through the thread, I have a errors,
Can't setup server on this port number.
Can't setup server on this port number.
but why?
class client:
import java.io.*;
import java.net.Socket;
// create class client
public class Client extends Thread {
Socket socket = null;
Socket socket1 = null;
// create send method
public void sendFile() throws IOException {
String host = "127.0.0.1";
String host1 = "127.0.0.2";
socket = new Socket(host, 4444);
socket1 = new Socket(host1, 444);
File file = new File("/home/reza/Desktop/link help");
File file1 = new File("/home/reza/Desktop/hi");
long length = file.length();
long length1 = file1.length();
byte[] bytes = new byte[(int) length];
byte[] bytes1 = new byte[(int) length1];
FileInputStream fis = new FileInputStream(file);
FileInputStream fis1 = new FileInputStream(file1);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
BufferedInputStream bis1 = new BufferedInputStream(fis1);
BufferedOutputStream out1 = new BufferedOutputStream(socket1.getOutputStream());
int count;
int count1;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
while ((count1 = bis1.read(bytes1)) > 0) {
out1.write(bytes1, 0, count1);
}
Thread t = new Thread(new Runnable() {
public void run()
{
while(socket.isConnected())
{
Wait2();
try {
sendFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
while(socket1.isConnected())
{
Wait2();
try {
sendFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
t.start();
t1.start();
fis.close();
fis1.close();
out.close();
bis.close();
out1.close();
bis1.close();
socket.close();
socket1.close();
}
public void Wait2()
{
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException x) {
System.out.println("Interrupted!");
}
}
}
// class server
import java.io.*;
import java.net.*;
public class Server {
public void recivefile() throws IOException {
ServerSocket serverSocket = null;
ServerSocket serverSocket1 = null;
try {
serverSocket = new ServerSocket(4444);
//serverSocket1 = new ServerSocket(444);
} catch (IOException ex) {
System.out.println("Can't setup server on this port number. ");
}
try {
serverSocket1 = new ServerSocket(444);
} catch (IOException ex) {
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
Socket socket1 = null;
InputStream is = null;
InputStream is1 = null;
FileOutputStream fos = null;
FileOutputStream fos1 = null;
BufferedOutputStream bos = null;
BufferedOutputStream bos1 = null;
int bufferSize = 0;
int bufferSize1 = 0;
try {
socket = serverSocket.accept();
socket1 = serverSocket1.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
is = socket.getInputStream();
is1 = socket1.getInputStream();
bufferSize = socket.getReceiveBufferSize();
bufferSize1 = socket1.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
System.out.println("file recieved");
System.out.println("Buffer size1: " + bufferSize1);
System.out.println("file recieved");
System.out.println("file recieved");
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
fos = new FileOutputStream("/home/reza/Desktop/reza");
bos = new BufferedOutputStream(fos);
fos1 = new FileOutputStream("/home/reza/Desktop/ali");
bos1 = new BufferedOutputStream(fos1);
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
byte[] bytes1 = new byte[bufferSize1];
int count1;
while ((count1 = is1.read(bytes1)) > 0) {
bos1.write(bytes1, 0, count1);
}
bos.flush();
bos.close();
bos1.flush();
bos1.close();
is.close();
is1.close();
socket.close();
serverSocket.close();
socket1.close();
serverSocket1.close();
}
public static void main(String[] args) throws IOException
{
System.out.println("server is run, please send file");
Server s = new Server();
s.recivefile();
}
}
error is :
Can't setup server on this port number.
Can't setup server on this port number.
You can't start a server on 127.0.0.2 - therein lies your problem.
netstat -ano | find "1024"
try above command if you are running your java files on windows environment that will help you to find any process using same port no as yours and also use
ex.printStackTrace() along with
System.out.println("Can't setup server on this port number.");
Assuming that your code runs on a unix platform, your server code is trying twice to open a socket on port 444, which is a system reserved port. In order to be able to succeed, your programme must run with administrative priviledges, and you must ensure that the port is not already used by another process.
A possible workaround is to:
use a port above 1024. These ports are free to use for userland programmes
in case of failure have a backup port, also above 1024. You must amend both server and client codes to try both ports, and of course your communication protocol must include some form of handshaking to make sure they are talking to the right interlocutor.
There are many other problems with your code listed in other answers.
you don't need to make every objects twice. Only one instance is enough in most cases,
if your server is running continuously and must accept many connections, you should not close the accepting socket at the end of one receiving session.
also the server is supposed to run a loop on the server socket accept call, and start a new thread for each incoming connection, whose job is to handle that connection.
While I understand your willingness to learn and experiment, there are existing solutions to what you are trying to achieve. For instance, you could simply use a FTP server for your purpose.
The way you have written client - server program is wrong I guess.
Following are the mistakes you have done...
1) In Client class, you have sendFile function in which you've created two threads - t & t1. In run function you are again calling the same sendFile function.
So it keeps creating threads under threads just like recursion.
2) In Server class, you are listening to two port within the same recieveFile function. As the socket = serverSocket.accept() is a blocking call, It wont excecute the rest of the code untill it finds a single client to connect.
So what exactly happens here is.. Once the first client connects, thenafter immediately it expects second client to connect.
In the mean time your client thread may try to access the port on which connection has not been established.
In short, your SERVER SHOULD BE IN A THREADING ENVIRONMENT NOT THE CLIENT.
And I would suggest that for different port you should use different server.
i.e. create different server class for both 1024 & 1025 port.