I have two simple classes:
Client:
public static void main(String[] args) throws IOException {
InetAddress addr = InetAddress.getByName(null);
Socket socket = null;
try {
socket = new Socket(addr, 1050);
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
in = new BufferedReader(isr);
OutputStreamWriter osw = new OutputStreamWriter( socket.getOutputStream());
BufferedWriter bw = new BufferedWriter(osw);
out = new PrintWriter(bw, false);
stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
// read user input
while (true) {
userInput = stdIn.readLine();
System.out.println("Send: " + userInput);
out.println(userInput);
out.flush();
String line = in.readLine();
while(line != null){
System.out.println(line);
line = in.readLine();
}
System.out.println("END");
}
}
catch (UnknownHostException e) {
// ...
} catch (IOException e) {
// ...
}
// close
out.close();
stdIn.close();
socket.close();
}
Server:
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter out = new PrintWriter(bw, /*autoflush*/true);
private void sendMessage(String msg1, String msg2) {
out.println(msg1);
// empy row
out.println("");
out.println(msg2);
}
The user enters a message, and this is sent to the server. Then, the server responds with N messages.
After the first request, the client stops and is never printed the word "END".
How do I send multiple messages at different times, with only one socket connection?
Firstly, you don't need to send an empty row, because you are sending by "line" and recieving by "line".
out.println(msg1);
out.println(msg2);
and
userInput = stdIn.readLine();
Here, userInput will only equal msg1
What I would recommend, would be not to loop on stdIn.readLine() = null, but have the client send, for example, "END_MSG", to notify the server that it will not send anymore messages.
Perhaps something like...
SERVER:
userInput =stdIn.readLine();
if(userInput.Equals("START_MSG");
boolean reading=true;
while(reading)
{
userInput=stdIn.readLine();
if(userInput.Equals("END_MSG")
{
//END LOOP!
reading = false;
}
else
{
//You have received a msg - do what you want here
}
}
EDIT:CLIENT:
private void sendMessage(String msg1, String msg2) {
out.println("START_MSG");
out.println(msg1);
out.println(msg2);
out.println("END_MSG");
}
(It also looks like in your question to have mixed up the client and the server?)
Related
I wrote this loop in my server, where he just sends some strings to a client:
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
for (int j = 0; j < i; j++) {
out.println(tmp[j]); // send the strings to the client
}
The client has another loop to retrieve all these strings but never exit from there. For example, if I send him 4 strings the output will be:
-hi
-how
-are
-you
And then after this last string it hangs and I cannot do anything else than closing the server. When I close it, the client exit from the while. This is the loop that doesn't work:
/* PHASE 2: The client receives the ArrayList with the emails */
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
String message[] = new String[5];
for (int j=0; ((line = in.readLine()) != null) && (line.length())>0;) {
System.out.println(line); //DEBUG
message[j++] = line;
if (j==5) {
data = format.parse(message[3]);
email.add(new Email((Integer.parseInt(message[0])), message[1], account, message[2], message[4], data));
j=0;
}
}
System.out.println("Out");
Here is the code of the client with the loop incriminated:
public void loadData() throws IOException, ClassNotFoundException, ParseException {
try {
connect();
ArrayList<Email> email = new ArrayList<Email>();
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date data;
/* PHASE 1: The client sends a string to the server */
try {
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
out.println(account+"\n"); // send the account name to server
/* PHASE 2: The client receives the ArrayList with the emails */
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
String message[] = new String[5];
for (int j=0; ((line = in.readLine()) != null) && (line.length())>0;) {
System.out.println(line); //DEBUG
message[j++] = line;
if (j==5) {
data = format.parse(message[3]);
email.add(new Email((Integer.parseInt(message[0])), message[1], account, message[2], message[4], data));
j=0;
}
}
System.out.println("Out");
Here is the server code:
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
private String nomeAccount = "";
public void run() {
try {
incoming = s.accept();
} catch (IOException ex) {
System.out.println("Unable to accept requests");
}
contenutoTextArea.append("Connected from: " + incoming.getLocalAddress() + "\n");
textarea.setText(contenutoTextArea.toString());
try {
//PHASE 1: The server receives the email
try {
BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
nomeAccount = in.readLine();
} catch (IOException ex) {
System.out.println("Not works");
}
//PHASE 2: I'm getting all the emails from the files
File dir = new File("src/server/" + nomeAccount);
String[] tmp = new String[100];
int i = 0;
for (File file : dir.listFiles()) {
if (file.isFile() && !(file.getName().equals(".DS_Store"))) {
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
tmp[i++] = line;
}
br.close();
} catch (IOException ex) {
System.out.println("Cannot read from file");
}
}
}
//PHASE 3: The server sends the ArrayList to the client
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
for (int j = 0; j < i; j++) {
out.println(tmp[j]); // send the strings to the client
}
} catch (IOException ex) {
System.out.println("Cannot send the strings to the client");
}
//PHASE 4: Here I loop and wait for the client choise
BufferedReader in;
String op;
boolean exit = false;
try {
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
while ((op = in.readLine()) != null) {
System.out.println("OP: " + op);
if (op.equals("Elimina")) {
String tmp = in.readLine();
contenutoTextArea.append("Ho eliminato la mail ").append(tmp).append(" \n");
textarea.setText(contenutoTextArea.toString());
File file = new File("src/server/" + nomeAccount + "/" + tmp + ".txt");
file.delete();
}
}
System.out.println("bbbbb");
} catch (IOException ex) {
System.out.println("Unable to read messages");
} finally {
try {
incoming.close();
} catch (IOException ex) {
System.out.println("Cannot close the socket");
}
}
}
}
Based on reading your client code, it looks like it's blocked waiting for another message, and it's not returning null because the end of the stream hasn't been reached. The fact that it continues once you kill the server process validates this.
As noted in the comments, you should make sure you close the PrintWriter on the server side. However, this by itself won't fix it, since the stream is on the socket, and as long as the socket is still open, this won't return null.
You can use specific control strings to communicate state back and forth (things that would never be user input, just to verify that round of communication is finished) then instead of checking for null, you'd check if the line matched the control string. Simply use that technique on both sides to pass control back and forth, and make sure to close the socket when done.
I am trying to pass message from server to client in terminal. What I would like the program to do is, in the client, it should be able to enter a command, get response from server, and be able to enter another command without restarting Client (by java Client).
Client.java
Socket socket = new Socket(host, port);
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String response = "";
boolean continuation = true;
while(continuation) {
Scanner input = new Scanner(System.in);
String command = (input.nextLine()).toString();
bw.write(command+"\r\n");
bw.flush();
if(command.equals("cmd1") {
while ((response = br.readLine()) != null) {
System.out.println(response);
}
}
System.out.println("This line will not execute as well.");
}
Server.java
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String[] in = br.readLine().split("\\s+");
String command = in[0];
if(command.equals("cmd1")) {
String response = "";
response = response + "RESPONSE:\r\n";
response = response + "This is a response.\r\n";
bw.write(response);
bw.flush();
}
If I don't put while((response = br.readLine()!= null) { ... } in Client.java, it is possible to enter multiple inputs in the terminal, but if I put it, it prints the response from the server and another input cannot be done without restarting Client.
Any help would be appreciated.
Thanks
This should work:
server:
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
boolean continuation = true;
while (continuation) {
String command = dis.readUTF();
//proceeed command
dos.writeUTF("response");
dos.flush();
}
Client:
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF("your command");
while (dis.available() == 0) {
try {
//wait for response
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(RandomTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
String response = dis.readUTF();
//and so on
Can anybody help me with this here. I am a newbie and I am working on a network application where I have to create a socket connection to the IP address and port that they already given me and then send XML message to the socket and finally include the ReadMe.txt file where I will save what I have received from the server. Here's my code
private static Socket socket;
public static void main(String args[])
{
try
{
socket = new Socket( "196.37.22.179", 9011);
//Send the message to the server
//PrintStream outstrm = null;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String str;
str = "<request>";
str += "<EventType>Authentication</EventType>";
str += "<event>";
str += "<UserPin>12345</UserPin>";
str += "<DeviceId>12345</DeviceId>";
str += "<DeviceSer>ABCDE</DeviceSer>";
str += "<DeviceVer>ABCDE</DeviceVer>";
str += "<TransType>Users</TransType>";
str += "</event></request>";
bw.write(str);
bw.flush();
System.out.println("Message sent to the server......! ");
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
You can use this code to store results from server in file
//Get the return message from the server
InputStream is = socket.getInputStream();
OutputStream outputStream = new FileOutputStream(new File("ReadMe.txt"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
Client will request for a file, if the file exist in server then the server send the file and give a confirmation message. So i want to take input using the main while loop but it stops working after first iteration,
client side
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class WebClient {
public static void main(String[] args) throws Exception {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
String req;
System.out.println("Do you want to search? (Y/N): ");
Scanner user_input = new Scanner(System.in);
req = user_input.next();
while (req.equals("Y")) {
Socket clientSocket = new Socket("localhost", 2000);
System.out.println("Enter the file name: ");
String file = inFromUser.readLine();
DataOutputStream serverOutput = new DataOutputStream(clientSocket.getOutputStream());
serverOutput.writeBytes(file + '\n');
BufferedReader serverInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Text from the file: ");
while (true) {
String data = serverInput.readLine();
if (data == null) {
break;
}
System.out.println(data);
}
clientSocket.close();
System.out.println("Do you want to search again? (Y/N): ");
req = user_input.next();
}
}
}
server side
import java.io.*;
import java.net.*;
public class WebServer {
public static void main(String[] args) throws Exception
{
ServerSocket welcomeSocket = new ServerSocket(2000);
while (true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
String file = inFromClient.readLine();
System.out.println("Client Request: " + file); //Show The Client Request File
String path = ("E://From Varsity//4.2//Lab//Network Programming//Java trying//New TCP-Client+Server//tcp")+ "/" + file ;
File objfile = new File(path);
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
if (objfile.exists())
{
String readfile = rfile(path);
outToClient.writeBytes("\n" +readfile + "200 ok \n"); // when exact file find
}
else
{
outToClient.writeBytes("404 The Requested File not found \n"); // file not found
}
}
}
public static String rfile(String file_N) throws Exception
{
StringBuilder app = new StringBuilder();
BufferedReader bufferR = new BufferedReader(new FileReader(file_N));
try
{
String line = bufferR.readLine(); // read file from buffer
while (line != null) {
app.append(line); // append the line
app.append("\n");
line = bufferR.readLine();
}
}
finally
{
bufferR.close();
}
return app.toString();
}
}
Any help will be appreciated , thanks in advance
java.net.Socket is blocking. It'll block until it receives a close (the call to readLine() blocks until more data is available)
3 solutions:
Simplest: add outToClient.close() after the write.
Nonblocking: Use java.nio.SocketChannel/java.nio.ServerSocketChannel
Threaded: Create a new thread each time ServerSocket.accept() fires with the Socket object from accept.
I have a task to do this.
Create a client and server socket interaction which accepts byte data and converts the byte data data received at server in the String and send back the response with the confirmation of the data conversation with success/unsuccess as the data passed will be with fix data length format so the validation should be done at server end.
As for e.g.
there are fields which ur sending to server like,
field 1 - number
field 2 - String
field 3 as Floating number i.e. 108.50
After conversion from byte to String :
152|any msg|108.50
In Byte it will be something like this,
10101|1001010010000000011000000000|1110111011
I have tried the following programs to do this
Server.java
public class Server extends Thread
{
private ServerSocket serverSocket;
public Server(int port) throws IOException
{
serverSocket = new ServerSocket(port);
//serverSocket.setSoTimeout(100000);
}
public void run()
{
while(true)
{
try
{
Socket server = serverSocket.accept();
byte Message[]=null;
DataInputStream in =
new DataInputStream(server.getInputStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
System.out.println("On this line"); //This doesnt get printed
buffer.flush();
data= buffer.toByteArray();
System.out.println(data);
String convertmsg = new String(data);
System.out.println("Msg converted "+convertmsg);
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
System.out.println("below dataoutputstream");
out.write("Success".getBytes());
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = 4003;
try
{
Thread t = new Server(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
client
public class Client {
public static void main(String args[]) throws IOException
{
int userinput =1;
while(userinput==1)
{
String serverName = "192.168.0.8";
int port = 4003;
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
System.out.println("above out.wirte()");
out.write("any msg".getBytes());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
System.out.println("converting array "+in);
byte[] data = IOUtils.toByteArray(in);
System.out.println(data);//This line doesnt get printed
//System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
System.out.println("Enter userinput ");
DataInputStream dis = new DataInputStream(System.in);
String s = dis.readLine();
userinput = Integer.parseInt(s);
}
}
}
If i send data from client to server in bytes,it reads it and prints it.Also then the line "Enter userinput " gets printed and if the user enters '1' the program continues.
But the problem is this program given above. If i try to send data from server stating "success"(meaning the data has been converted from bytes to String successfully) then the program stucks and the cursor doesnt go below the line which are in comments "This line doesnt get printed".There is no error printed and none of the program terminates.I am new to socket programming and dont understand much about networking.
Any help will be truly appreciated.
You're reading the input until end of stream, but the peer isn't closing the connection, so end of stream never arrives.
I suggest you read and write lines, or use writeUTF() and readUTF().