I have 2 classes (Client and Server) used to implement simple communication in my application. My code is shown below:
Server:
public class Server {
public static void main(String[] ar) {
int port = 1025; // just a random port. make sure you enter something between 1025 and 65535.
try {
ServerSocket ss = new ServerSocket(port); // create a server socket and bind it to the above port number.
System.out.println("Waiting for a client...");
Socket socket = ss.accept();
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("enter meter id ");
String line = null;
while (true) {
line = in.readUTF(); // wait for the client to send a line of text.
System.out.println("client send me this id number " + line);
line = keyboard.readLine();
out.writeUTF(line);
out.flush();
//line = in.readUTF();
System.out.println("Waiting for the next line...");
System.out.println();
}
} catch (Exception x) {
x.printStackTrace();
}
}
}
Client:
public class Client {
public static void main(String[] ar) {
int serverPort = 1025;
String address = "localhost";
try {
InetAddress ipAddress = InetAddress.getByName(address); // create an object that represents the above IP address.
System.out.println(" IP address " + address + " and port "
+ serverPort);
Socket socket = new Socket(ipAddress, serverPort); // create a socket with the server's IP address and server's port.
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
// Create a stream to read from the keyboard.
BufferedReader keyboard = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
System.out.println("ClientConnected.");
System.out.println("enter meter id");
while (true) {
line = keyboard.readLine(); // wait for the user to type in something and press enter.
System.out.println("Sending this number to the server...");
out.writeUTF(line); // send the above line to the server.
out.flush(); // flush the stream to ensure that the data reaches the other end.
line = in.readUTF(); // wait for the server to send a line of text.
System.out
.println("The server was very polite. It sent me this : "
+ line);
System.out.println();
}
}
catch (Exception x) {
x.printStackTrace();
}
}
}
My problem is that while testing the program I do get communication between the client and server, but while debugging, with a break point on the out.flush line in Server.java, it does not go to the intended destination. This intended destination being the line line = in.readUTF(); of Client.java. Can anyone help me to solve this?
It is good practice to open the OutputStreams before the InputStreams, on your sockets, as said in this question.
This question also clarifies that.
What I suspect here is your client and server are running in two different JVM processes and java debugger cannot debug two JVM at the same time.
Related
I am running a client server program on port 80 (currently says port 2040 for testing purposes only). Whenever I run my server on my client side/browser, the console displays this weird text, when it should be returning a HTMl file that i scannned in. However, when I run my IP address on my browser, it returns the necessary code. Why?
Here is my code:
public class ServerSide {
public static void main(String[] args) throws Exception {
//port used
int port = 2040;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Running on port " +port);
/*server always on
* creating a connection socket when contacted by client..
*/
while(true) {
//create connection socket when contacted
Socket client = serverSocket.accept();
//read input from client
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
//whatever input or communication we want to have can operate in this string..
String x;
while((x = input.readLine()) != null){
System.out.println(x);
if(x.isEmpty()) {
break;
}
}
//output of client server..
OutputStream clientOutput = client.getOutputStream();
clientOutput.write("HTTP/1.1 200 OK\r\n".getBytes());
clientOutput.write("\r\n".getBytes());
clientOutput.write("".getBytes());
clientOutput.write("\r\n\r\n".getBytes());
Scanner fetch = new Scanner(new File("index.html"));
String myHTML_file = fetch.useDelimiter("\\Z").next();
fetch.close();
clientOutput.write(myHTML_file.getBytes("UTF-8"));
clientOutput.write("\r\n\r\n".getBytes());
clientOutput.flush();
System.out.println("Connection closed.");
clientOutput.close();
}
}
}
A Client socket Program (in windows VM) generates integer from 1 to 10 as per below code
public class ClientSocket {
public static void main(String[] args)
{
try{
InetAddress inetAddress = InetAddress.getLocalHost();
String clientIP = inetAddress.getHostAddress();
System.out.println("Client IP address " + clientIP);
Integer dataSendingPort ;
dataSendingPort = 6999 ;
Socket socket = new Socket("192.168.0.32",dataSendingPort);
String WelcomeMessage = " hello server from " + clientIP ;
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
if(socket.isConnected()){
System.out.println("connection was successful");
}
else{
System.out.println("Error- connection was not successful");
}
for (int x= 0 ; x< 10 ; x++){
bufferedWriter.write(x);
bufferedWriter.flush();
}
bufferedWriter.close();
}
catch (IOException e){
System.out.println(e);
}// catch
finally{
System.out.println("closing connection");
}
} // main
} // class
My server socket program is running on Mac OS as Host Machine, whose code is shown below
public class MyServer {
public static void main(String[] args) throws Exception {
try {
// get input data by connecting to the socket
InetAddress inetAddress = InetAddress.getLocalHost();
String ServerIP = inetAddress.getHostAddress();
System.out.println("\n server IP address = " + ServerIP);
Integer ListeningPort ;
ListeningPort = 6999 ;
ServerSocket serverSocket = new ServerSocket(ListeningPort);
System.out.println("server is receiving data on port # "+ ListeningPort +"\n");
// waiting for connection form client
Socket socket = serverSocket.accept();
if(socket.isConnected()){
System.out.println("Connection was successful");
}
else {
System.out.println("connection was not successful");
}
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Integer s = 0 ;
while (( s = input.read()) >= 0){
System.out.println(input.read());
}
} //try
catch (IOException e)
{
System.out.println(e);
} // catch
} //main
} //socket class
The issue is that output I am receiving is -1 when I use while loop and receive first value i.e 0 without using a loop.
However, I was able to send a single value from client to server, but
how can I send Stream of Values from the client and print it on Server
Side.
Suggestions are most welcome
-1 means end of stream.
Closing the input or output stream of a stock closes the socket.
socket.isConnected() cannot possibly be false at the point you are testing it.
input.ready() isn't a test for end of stream, or end of message, or end of transmission, or anything useful at all really.
Don't flush inside loops.
I am trying to make a socket server, I am connecting through putty to this server. Whenever I type "hi" it says "no" rather than "hi" which I want it to do. I found this on A java website. If you could tell me what I am doing wrong that would be great. Thanks!
int port = 12345;
ServerSocket sock = new ServerSocket(port);
System.out.println("Server now active on port: " + port);
Socket link = sock.accept();
System.out.println("Interface accepted request, IP: " + link.getInetAddress());
BufferedReader input = new BufferedReader(new InputStreamReader(link.getInputStream()));
PrintWriter output = new PrintWriter(link.getOutputStream(), true);
output.println("ISEEYOU");
String inputLine;
Thread.sleep(1500);
while((inputLine = input.readLine()) != null) {
if(inputLine.equals("hi")) {
output.println("hi");
}else{
output.println("no");
}
}
Your Java program is correct.
I've tried your code, just added System.out.printf("[%s]", inputLine); as first line in the while loop to ensure, what I get from putty.
I guess your problem is the protocol putty uses to connect. It worked with RAW for me. See below the session setting I've used:
EDIT:
According to your comment I added some code for a simple client, that reads the line from console, sends it to the server and prints the echo back to console.
public void Client() throws IOException {
// Client that closes the communication when the user types "quit"
Socket socket = new Socket("localhost", 8080);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
BufferedReader user = new BufferedReader(new InputStreamReader(System.in));
String line;
while(!(line = user.readLine()).equals("quit")) {
ps.println(line); // Write to server
System.out.println(reader.readLine()); // Receive echo
}
socket.shutdownOutput(); // Send EOF to server
socket.close();
}
The corresponding server would look like this:
public void server() throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
// Just read a line and echo it till EOF
String line;
while((line = reader.readLine()) != null) ps.println(line);
}
You might need to change the port I used here, if 8080 is already binded on your machine. Also you might want to have the server running on another computer then the client. In this case you need to change "localhost".
So I am trying to have a sever sit and listen waiting for a connection from a client. The client sends over some string and the sever does some action based on whats received. Now what I would like to happen is the client sends over some command asking for data back and have the server get what it needs to and send the string back.
Not a big deal right? Well for some reason I can't get it working, my best guess is that its not closing the socket properly. I can't figure out why it wouldn't or what I am doing wrong.
Client
String data = "";
DataOutputStream outToServer = null;
BufferedReader input;
try {
outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes("GETDATA");
outToServer.flush();
input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
data = input.readLine();
Log.d("ANSWER: ", data);
input.close();
} catch (IOException e) {
Log.d("Error: ", e.toString());
}
Server
ServerSocket listeningSocket = new ServerSocket(9008);
BufferedReader fromClient ;
PrintStream os;
while(true) {
Socket clientSocket = listeningSocket.accept();
ServerConnection clientConnection = new ServerConnection(clientSocket);
os = new PrintStream(clientSocket.getOutputStream());
fromClient= new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
if(fromClient.readLine().equals("GETDATA")){
os.println("DATA");
os.flush();
clientSocket.wait();
clientSocket.close();
}
else{
clientConnection.run();
}
}
Any ideas?
here is your error
outToServer.writeBytes("GETDATA");
the right code is
outToServer.writeBytes("GETDATA\n");
as your using readline you should send a full line with line break
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();
}
}