I have a problem in a client-server application. The client sends a picture to the server and the server responds with a reply message.
Here is my server code:
public class Server
{
public static void main(String[] args) throws Exception
{
String response="response";
ServerSocket socket = new ServerSocket(3333);
while (true)
{
Socket clientSocket = socket.accept();
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
FileOutputStream fout = new FileOutputStream("output.jpg");
int i;
while ( (i = dis.read()) > -1)
fout.write(i);
DataOutputStream outToClient= new DataOutputStream(clientSocket.getOutputStream());
outToClient.writeBytes(response);
fout.flush();
fout.close();
dis.close();
outToClient.close();
clientSocket.close();
}
}
}
Client:
public static void main(String[] args) throws Exception
{
// TODO Auto-generated method stub
String sentence;
int i;
FileInputStream fis = new FileInputStream ("pathphoto.jpg");
Socket sock = new Socket ("hostname",3333);
DataOutputStream os = new DataOutputStream(sock.getOutputStream());
System.out.println("Sending....");
while ((i = fis.read()) > -1)
os.write(i);
BufferedReader inFromServer= new BufferedReader(new InputStreamReader(sock.getInputStream()));
sentence=inFromServer.readLine();
System.out.println("FROM SERVER: " + sentence);
fis.close();
os.close();
sock.close();
}
}
The problem is that the client doesn't receive the response from the server and I think along these lines:
BufferedReader inFromServer= new BufferedReader(new InputStreamReader(sock.getInputStream()));
sentence=inFromServer.readLine();
Because without them the server sends the response.
Any advice on how to fix it?
Its not stuck in BufferedReader, it is actually stuck in
while ((i = fis.read()) > -1)
Since your client never told server length of stream, or closed stream server will try to read next byte from inputstream and will be stuck when client is done sending file and waiting for response from server.
When you remove code to read response back from server, client goes ahead and closes all streams and in that case server reads a -1 and goes ahead.
Related
The client sends data (string) to the server, and the server must read it, but in my case the server didn't read the data (value) that the client sent, and I didn't know where is the problem exactly, because normally the steps to read data are all correct in the server side
Client side:
Socket socket = new Socket(address, authenticationServerPort);
username = username + "\n"; // to send username through socket without
String h=getUserInput();
// waiting
// Send the message to the server
// send public key
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
System.out.println(h);
bw.write(h);
bw.flush();
System.out.println("Message sent to the Authentication server : "+ h);
Server side:
Socket clientSocket = null;
try {
System.out.println("Server Running");
int serverPort = 8029; // the server port we are using
ServerSocket listenSocket = new ServerSocket(serverPort);
List<BlockChain> resultList = new ArrayList<BlockChain>();
while (true) {
clientSocket = listenSocket.accept();
InputStream is = clientSocket.getInputStream();
System.out.println(is);
InputStreamReader isr = new InputStreamReader(is);
System.out.println(isr);
BufferedReader br = new BufferedReader(isr);
String request = br.readLine();
System.out.println("the msg receving from client is : "+request);
PrintWriter out;
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())));
if (clientSocket != null) {
clientSocket.close();
}
}
catch (Exception e) {
e.printStackTrace();// TODO: handle exception
}
}
Someone tell me where is the problem exactly.
I am trying to create a Client-Server model of file transferring in Java in which the client will read a file and send the data to the server and the server will receive the data and write it to a file. I had already seen this post, but it deals with C.
I wrote a simple algorithm which would just send the file as soon it connects to the server.
This is the code for the client:
import java.io.*;
import java.net.Socket;
public class Client {
public static void main(String args[]) {
try {
Socket s = new Socket(args[0], Integer.parseInt(args[1]));
System.out.println("Connected to " + s.getRemoteSocketAddress());
DataInputStream din = new DataInputStream(s.getInputStream());
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
File file = new File(args[2]);
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int no_of_bytes = 0;
while ((no_of_bytes = fis.read(buffer)) != -1) {
dout.write(buffer, 0, no_of_bytes);
}
} catch (Exception e) {
System.err.println(e.getLocalizedMessage());
}
}
}
This is the code for the server:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String args[]) {
try {
ServerSocket ss = new ServerSocket(Integer.parseInt(args[0]));
Socket s = ss.accept();
System.out.println("Connected to " + s.getRemoteSocketAddress());
DataInputStream din = new DataInputStream(s.getInputStream());
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
File new_file = new File("/home/Puspam/Videos/received.png");
new_file.createNewFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(new_file));
int a;
while ((a = din.read()) != -1) {
bw.write((char) a);
}
din.close();
bw.flush();
} catch (Exception e) {
System.err.println(e.getLocalizedMessage());
}
}
}
After running the two programs with an image file for the experiment, I could find that the file has not been transferred properly. When I try to open the received file, the image viewer software in my PC shows an error that it is not a valid image file. Also, I could see that the received file is a bit larger than the original one.
What mistake am I doing here?
I've had this kinda thing before. Try to use the same type of Input/Output Stream on both ends. Like, BufferedReader to BufferedWriter, etc. You're using a FileInputStream in conjunction with a BufferedWriter. Also, you may need to flush the BufferedWriter in every iteration of your for loop.
I have implemented a client/server to send files . When there is no more messages exchanged after sending the file , the code works perfectly , but if the client sends some string to the server directly after the code of receiving the file both client and server stop doing anything and the file is not sent it's something like if they both get stuck in deadlock but I'm not really sure :
Here is the code to send the file without sending anything after it , which works:
Client
String filename;
BufferedReader UIn = new BufferedReader(new InputStreamReader(System.in));
Socket peer = new Socket("localhost",9999);
System.out.print("Enter the file name to download :");
filename= UIn.readLine();
///////////////////////////////
DataOutputStream OutToServer;
OutToServer = new DataOutputStream(peer.getOutputStream());
OutToServer.writeBytes(filename+"\n");
FileOutputStream fos = new FileOutputStream(new File("D:/new.txt"));
BufferedOutputStream out = new BufferedOutputStream(fos);
InputStream in = peer.getInputStream();
buffer = new byte[1024];
while((count=in.read(buffer))>0)
{
fos.write(buffer, 0, count);
System.out.println(buffer);
}
fos.close();
System.out.println("done");
Server:
ServerSocket server =null;
try {
server = new ServerSocket(9999);
while(true)
{
client= server.accept();
//System.out.println("Connection accepted");
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
DataOutputStream outToclient =new DataOutputStream(client.getOutputStream());
String request=inFromClient.readLine();
file = new File(request);
if (file.exists())
{
OutputStream out = client.getOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
while((count =in.read(buffer)) >0)
{
out.write(buffer,0,count);
out.flush();
}
}
// System.out.println(request);
// outToclient.writeBytes("alaa\n");
}
} catch (IOException ex) {
Logger.getLogger(ServerWork.class.getName()).log(Level.SEVERE, null, ex);
}
But if I try to send anything after the loop between client and server it stops working . Is it because I'm using readLine() and writeBytes()?
You are using both DataOutputStream and OutputStream. I think that they
should work together but what I guess you should do is to flush the buffer (or close it).
After you're done writing everything you want to send, some data may still be in the buffer. Now you will have to flush the buffer, to force it to send all the data.(as it is said here).
outToclient.writeBytes("alaa\n");
outToclient.flush();
i have this assignment where i am supposed to write a proxy server that uses java sockets to handle get requests from a client. I am now stuck and have been looking all over google to find the answer but without success.
Christoffers solution helped my with my first problem. Now that i have updated the code this is what i am using.
The problem is that it only downloads parts of most webpages before it gets stuck on sending the packets back to the client loop. At the moment I cant explain why it is behaving the way it is.
public class MyProxyServer {
//Set the portnumber to open socket on
public static final int portNumber = 5555;
public static void main(String[] args){
//create and start the proxy
MyProxyServer myProxyServer = new MyProxyServer();
myProxyServer.start();
}
public void start(){
System.out.println("Starting MyProxyServer ...");
try {
//create the socket
ServerSocket serverSocket = new ServerSocket(MyProxyServer.portNumber);
while(true)
{
//wait for a client to connect
Socket clientSocket = serverSocket.accept();
//create a reader to read the instream
BufferedReader inreader = new BufferedReader( new InputStreamReader(clientSocket.getInputStream(), "ISO-8859-1"));
//string builder for preformance when we loop over the inputstream and read lines
StringBuilder builder = new StringBuilder();
String host = "";
for (String buffer; (buffer = inreader.readLine()) != null;) {
if (buffer.isEmpty()) break;
builder.append(buffer.replaceAll("keep-alive", "close"));
if(buffer.contains("Host"))
{
//parse the host
host = buffer.replaceAll("Host: ", "");
}
System.out.println(buffer);
}
String req = builder.toString();
System.out.println("finshed reading \n" + req);
System.out.println("host: " + host);
//new socket to send the information over
Socket s = new Socket(InetAddress.getByName(host), 80);
//printwriter to send text over the output stream
PrintWriter pw = new PrintWriter(s.getOutputStream());
//send the request from the client
pw.println(req+"\r\n");
pw.flush();
//create inputstream to receive the web page from the host
BufferedInputStream in = new BufferedInputStream(s.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outbuffer = new BufferedOutputStream(clientSocket.getOutputStream());
byte[] bytebuffer = new byte[1024];
int bytesread;
//send the response back to the client
while((bytesread = in.read(bytebuffer)) != -1) {
System.out.println(bytesread);
outbuffer.write(bytebuffer,0, bytesread);
outbuffer.flush();
}
System.out.println("done sending");
//close the streams
inreader.close();
s.close();
pw.close();
outbuffer.close();
in.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch(RuntimeException e){
e.printStackTrace();
}
}
}
If anyone could explain to me why i cant get it working correctly and how to solve it I would be very grateful!
Thanks in advance.
I have implement the simple TCP server and TCP client classes which can send the message from client to server and the message will be converted to upper case on the server side, but how can I achieve transfer files from server to client and upload files from client to server. the following codes are what I have got.
TCPClient.java:
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String args[]) throws Exception {
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("127.0.0.1", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + "\n");
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
TCPServer.java:
import java.io.*;
import java.net.*;
class TCPServer {
public static void main(String args[]) throws Exception {
int firsttime = 1;
while (true) {
String clientSentence;
String capitalizedSentence="";
ServerSocket welcomeSocket = new ServerSocket(3248);
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
//System.out.println(clientSentence);
if (clientSentence.equals("set")) {
outToClient.writeBytes("connection is ");
System.out.println("running here");
//welcomeSocket.close();
//outToClient.writeBytes(capitalizedSentence);
}
capitalizedSentence = clientSentence.toUpperCase() + "\n";
//if(!clientSentence.equals("quit"))
outToClient.writeBytes(capitalizedSentence+"enter the message or command: ");
System.out.println("passed");
//outToClient.writeBytes("enter the message or command: ");
welcomeSocket.close();
System.out.println("connection terminated");
}
}
}
So, the TCPServer.java will be executed first, and then execute the TCPClient.java, and I try to use the if clause in the TCPServer.java to test what is user's input,now I really want to implement how to transfer files from both side(download and upload).Thanks.
So lets assume on server side you have received the file name and file path. This code should give you some idea.
SERVER
PrintStream out = new PrintStream(socket.getOutputStream(), true);
FileInputStream requestedfile = new FileInputStream(completeFilePath);
byte[] buffer = new byte[1];
out.println("Content-Length: "+new File(completeFilePath).length()); // for the client to receive file
while((requestedfile.read(buffer)!=-1)){
out.write(buffer);
out.flush();
out.close();
}
requestedfile.close();
CLIENT
DataInputStream in = new DataInputStream(socket.getInputStream());
int size = Integer.parseInt(in.readLine().split(": ")[1]);
byte[] item = new byte[size];
for(int i = 0; i < size; i++)
item[i] = in.readByte();
FileOutputStream requestedfile = new FileOutputStream(new File(fileName));
BufferedOutputStream bos = new BufferedOutputStream(requestedfile);
bos.write(item);
bos.close();
fos.close();
Assuming you want to continue to support sending messages as well as sending files back and forth...
As you have now, you are using writeBytes to send data from client to server.
You can use that to send anything, like the contents of files...
But you will need to define a protocol between your client and server so that they know when a file is being transferred rather than a chat message.
For example you could send the message/string "FILECOMING" before sending a file to the server and it would then know to expecting the bytes for a file. Similarly you'd need a way to mark the end of a file too...
Alternatively, you could send a message type before each message.
A more performant/responsive solution is to do the file transfer on a separate thread/socket - this means that the chat messages are not held up by the transfers. Whenever a file transfer is required, a new thread/socket connection is created just for that.
~chris
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String argv[]) throws IOException
{
String sentence;
String modifiedSentence;
Socket clientSocket = new Socket("*localhost*", *portnum*); // new Socket("192.168.1.100", 80);
System.out.println("Enter your ASCII code here");
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
sentence = inFromUser.readLine();
// System.out.println(sentence);
while(!(sentence.isEmpty()))
{
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(sentence);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
modifiedSentence = inFromServer.readLine();
while(!(modifiedSentence.isEmpty()))
{
System.out.println("FROM SERVER: " + modifiedSentence);
break;
}
System.out.println("Enter your ASCII code here");
inFromUser = new BufferedReader( new InputStreamReader(System.in));
sentence = inFromUser.readLine();
}
System.out.println("socket connection going to be close");
clientSocket.close();
}
}