I want to programm al small "chat" Programm using TLS
I am having trouble with SSL Sockets an Input streams. The TLS part works fine.
My Problem is : "bufferedreader.ready()" always returns false.
if i delete teh if -satetmant if works "fine". The programm waits until there is an \n or \r and prints is to System.out. But I can not send messages in that time.
"client"
InputStream inputstream = System.in;
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
InputStream inputstream1 = socket.getInputStream();
InputStreamReader inputstreamreader1 = new InputStreamReader(inputstream1);
BufferedReader bufferedreader1 = new BufferedReader(inputstreamreader1);
OutputStream outputstream = socket.getOutputStream();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
OutputStream outputstream1 = System.out;
OutputStreamWriter outputstreamwriter1 = new OutputStreamWriter(outputstream1);
BufferedWriter bufferedwriter1 = new BufferedWriter(outputstreamwriter1);
//Mitteilen, welchen Kommprofil zum verbindugn genutzt werden soll.
bufferedwriter.write("bez\n");
while (true) {
if (bufferedreader.ready()) {
bufferedwriter.write(bufferedreader.readLine() + '\n');
bufferedwriter.flush();
}
if (bufferedreader1.ready()) {
bufferedwriter1.write(bufferedreader1.readLine() + '\n');
bufferedwriter1.flush();
}
}
"Server":
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
InputStream inputstream1 = System.in;
InputStreamReader inputstreamreader1 = new InputStreamReader(inputstream1);
BufferedReader bufferedreader1 = new BufferedReader(inputstreamreader1);
OutputStream outputstream = System.out;
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
OutputStream outputstream1 = sslsocket.getOutputStream();
OutputStreamWriter outputstreamwriter1 = new OutputStreamWriter(outputstream1);
BufferedWriter bufferedwriter1 = new BufferedWriter(outputstreamwriter1);
while (true ) {
if (bufferedreader.ready()) {
bufferedwriter.write(bufferedreader.readLine() + '\n');
bufferedwriter.flush();
}
if (bufferedreader1.ready()) {
bufferedwriter1.write(bufferedreader1.readLine() + '\n');
bufferedwriter1.flush();
}
}
As you have nothing else to do in your loop except call readLine(), just call it. It will block until something arrives. You don't need to call ready() at all in thus situation, or indeed in its any situation.
I "solved" my Problem with this workaround:
public class CopyStreamThread extends Thread {
private BufferedWriter out;
private BufferedReader in;
public CopyStreamThread(BufferedWriter out, BufferedReader in) {
this.out = out;
this.in = in;
}
#Override
public void run() {
while (true) {
try {
out.write(in.readLine() + '\n');
out.flush();
} catch (IOException ex) {
Logger.getLogger(CopyStreamThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
"clinet/Server"
new CopyStreamThread(bufferedwriter, bufferedreader).start();
new CopyStreamThread(bufferedwriter1, bufferedreader1).start();
i divided the waitung for input in 2 threads which isnt a nice soulution but it works.
Thanks for support.
Related
I have a server and client application. They both use a BufferedWriter-InputStreamReader-InputStream to read information coming from the server, or coming from the client
I have it working so I can use
bw.write("command");
to execute a command on the server side, and output the information back to the client-side.
However, I am running into trouble doing it twice, for two different commands. Here's the code:
Server-sided code:
public void run() {
try {
while (true) {
socket.setTcpNoDelay(true);
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String input = br.readLine();
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
if (input.equals("increment")) {
bw.write(String.valueOf(totalBets.incrementAndGet()));
bw.newLine();
bw.flush();
} else if(input.equals("generate")) {
Random rand = new Random();
bw.write(String.valueOf(rand.nextDouble()*99));
bw.newLine();
bw.flush();
}
}
}
Client-sided code:
public void actionPerformed(ActionEvent arg0) {
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
bw.write("increment" + "\n");
bw.flush();
String id = br.readLine();
bw.write("generate");
bw.flush();
String roll = br.readLine();
}
}
The first String id gets the output from running the bw.write("increment"), but when I try to run bw.write("generate"), it freezes when running the line: String roll = br.readLine();
Any help?
Thank you!
I suggest that you use PrintWriter rather than BufferedWriter. Use BufferedReader to read without leaving data in the underlying operating system's buffers, so they will be buffered at application level, but for writing you want it to go out as soon as you send one complete 'command'.
With a PrintWriter you can also use println which should solve your problem.
You're losing data, or risking it, by creating multiple BufferedReaders. Use the same one for the life of the socket. Ditto the BufferedWriter.
i'm new to java. I'm trying to create a simple java file server from where the clients can request for a file and download it. basically when a client requests for a file it will simply will be written from server's folder to client folder. When i run my code it does not show any error but the file that client requested is not written to it's folder either.
my client side code:
public void download(Socket s) throws Exception {
DataInputStream din=new DataInputStream(s.getInputStream());
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
PrintWriter w = new PrintWriter(s.getOutputStream(), true);
System.out.print("Enter File Name :");
String request = con.readLine();
w.println(request);
String msg = r.readLine();
if (msg.startsWith("ERROR")) {
System.out.println("File not found on Server ...");
return;
} else if (msg.startsWith("FOUND")) {
System.out.println("Receiving File ...");
File f = new File(request);
if (f.exists()) {
String Option;
System.out.println("File Already Exists. Want to OverWrite (Y/N) ?");
Option = con.readLine();
if (Option == "N") {
dout.flush();
return;
}
}
FileOutputStream fileout = new FileOutputStream(f);
int ch;
String temp;
do {
temp = din.readLine();
ch = Integer.parseInt(temp);
if (ch != -1) {
fileout.write(ch);
}
} while (ch != -1);
fileout.close();
System.out.println(din.readLine());
}
}
The server side:
public class Fileagent extends Thread {
Socket client;
DataInputStream din;
DataOutputStream dout;
ServerSocket soc;
PrintWriter w;
BufferedReader r;
public Fileagent(Socket soc) {
try {
client = soc;
din = new DataInputStream(client.getInputStream());
dout = new DataOutputStream(client.getOutputStream());
w = new PrintWriter(client.getOutputStream(), true);
r = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
System.out.println("FTP Client Connected ...");
start();
} catch (Exception ex) {
}
}
public void upload() throws Exception {
w.println("SEnding.....");
String file = r.readLine();
File f = new File(file);
if (!f.exists()) {
w.println("ERROR");
return;
} else {
w.println("FOUND");
FileInputStream fin = new FileInputStream(f);
int ch;
do {
ch = fin.read();
w.println(String.valueOf(ch));
} while (ch != -1);
fin.close();
}
I'm trying to send simple text files but the files is not being send to clients.
Thanks in advance.
I suspect the problem is that you are not flushing your PrintWriter after sending the request from the client to the server:
w.println(request);
w.flush();
You seem to be using a PrintWriter on the server side as well. Make sure to call w.flush() or w.close() when you are done sending stuff over.
Also, I assume you realize that this is an extremely inefficient way to send the file over.
It looks like your problem stems from this
String request=con.readLine();
You're always reading from this con object. But you're passing in a Socket s to the method.
There are other problems, such as what Gray mentioned, and also that you're writing each character on its own line, but those are just messed up formatting; they shouldn't prevent you from getting a file at all...
What I am trying to do is to read in data from a socket connection then write all of that to a file. My reader and all the related statements are below. Any ideas why it is not working? If you can see a more efficient way to do this that would also be useful.
(My full code does successfully connect to the socket)
EDIT: Added more of my code.
public static void main(String args[]) throws IOException
{
Date d = new Date();
int port = 5195;
String filename = "";
//set up the port the server will listen on
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(port));
while(true)
{
System.out.println("Waiting for connection");
SocketChannel sc = ssc.accept();
try
{
Socket skt = new Socket("localhost", port);
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
FileWriter logfile = new FileWriter(filename);
BufferedWriter out = new BufferedWriter(logfile);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
while ((inputLine = stdIn.readLine()) != null)
{
System.out.println("reading in data");
System.out.println(inputLine);
out.write(inputLine);
System.out.println("echo: " + in.readLine());
}
sc.close();
System.out.println("Connection closed");
}
You program requires you to type in a line for every line you read from the socket. Are you typing enough lines?
The lines you read from the console are written to the file, did you expect the lines from the socket to be written to the file?
Where are you closing the file (and the socket)
Another approach is to use a utility like Apache IOUtils
Socket skt = new Socket("localhost", port);
IOUtils.copy(skt.getInputStream(), new FileOutputStream(filename));
skt.close();
I think there's a typo in this line:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
Change "System.in" to just "in":
BufferedReader stdIn = new BufferedReader(new InputStreamReader(in));
FYI, here is how I like to read sockets. I prefer to avoid the string encoding offered by the readers, and just go straight for raw bytes:
byte[] buf = new byte[4096];
InputStream in = skt.getInputStream()
FileOutputStream out = new FileOutputStream(filename);
int c;
while ((c = in.read(buf)) >= 0) {
if (c > 0) { out.write(buf, 0, c); }
}
out.flush();
out.close();
in.close();
Oh, cute, turns out that code is essentially what IOUtils.copy() does (+1 to Peter Lawrey!):
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/CopyUtils.java?view=markup#l193
This is a logging function which logs error stream from the execution of an external program. Everything works fine. But I do not want to generate the log file when there is no data in error stream. Currently it is creating zero size file. Please help.
FileOutputStream fos = new FileOutputStream(logFile);
PrintWriter pw = new PrintWriter(fos);
Process proc = Runtime.getRuntime().exec(externalProgram);
InputStreamReader isr = new InputStreamReader(proc.getErrorStream());
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
{
if (pw != null){
pw.println(line);
pw.flush();
}
}
Thank you.
Simply defer the creating of the FileOutputStream and PrintWriter until you need it:
PrintWriter pw = null;
Process proc = Runtime.getRuntime().exec(externalProgram);
InputStreamReader isr = new InputStreamReader(proc.getErrorStream());
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null)
{
if (pw == null)
{
pw = new PrintWriter(new FileOutputStream(logFile));
}
pw.println(line);
pw.flush();
}
Personally I'm not a big fan of PrintWriter - the fact that it just swallows all exceptions concerns me. I'd also use OutputStreamWriter so that you can explicitly specify the encoding. Anyway, that's aside from the real question here.
The obvious thing to do is to change
FileOutputStream fos = new FileOutputStream(logFile);
PrintWriter pw = new PrintWriter(fos);
....
if (pw != null){
...
}
to
FileOutputStream rawLog = null;
try {
PrintWriter Log = null;
....
if (log == null) {
rawLog = new FileOutputStream(logFile);
log = new PrintWriter(log, "UTF-8");
}
...
} finally {
// Thou shalt close thy resources.
// Icky null check - might want to split this using the Execute Around idiom.
if (rawLog != null) {
rawLog.close();
}
}
i have a file that have some non-utf8 caracters (like "ISO-8859-1"), and so i want to convert that file (or read) to UTF8 encoding, how i can do it?
The code it's like this:
File file = new File("some_file_with_non_utf8_characters.txt");
/* some code to convert the file to an utf8 file */
...
edit: Put an encoding example
The following code converts a file from srcEncoding to tgtEncoding:
public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException {
BufferedReader br = null;
BufferedWriter bw = null;
try{
br = new BufferedReader(new InputStreamReader(new FileInputStream(source),srcEncoding));
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding));
char[] buffer = new char[16384];
int read;
while ((read = br.read(buffer)) != -1)
bw.write(buffer, 0, read);
} finally {
try {
if (br != null)
br.close();
} finally {
if (bw != null)
bw.close();
}
}
}
--EDIT--
Using Try-with-resources (Java 7):
public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException {
try (
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), srcEncoding));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding)); ) {
char[] buffer = new char[16384];
int read;
while ((read = br.read(buffer)) != -1)
bw.write(buffer, 0, read);
}
}
String charset = "ISO-8859-1"; // or what corresponds
BufferedReader in = new BufferedReader(
new InputStreamReader (new FileInputStream(file), charset));
String line;
while( (line = in.readLine()) != null) {
....
}
There you have the text decoded. You can write it, by the simmetric Writer/OutputStream methods, with the encoding you prefer (eg UTF-8).
You need to know the encoding of the input file. For example, if the file is in Latin-1, you would do something like this,
FileInputStream fis = new FileInputStream("test.in");
InputStreamReader isr = new InputStreamReader(fis, "ISO-8859-1");
Reader in = new BufferedReader(isr);
FileOutputStream fos = new FileOutputStream("test.out");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
Writer out = new BufferedWriter(osw);
int ch;
while ((ch = in.read()) > -1) {
out.write(ch);
}
out.close();
in.close();
You only want to read it as UTF-8?
What I did recently given a similar problem is to start the JVM with -Dfile.encoding=UTF-8, and reading/printing as normal. I don't know if that is applicable in your case.
With that option:
System.out.println("á é í ó ú")
prints correctly the characters. Otherwise it prints a ? symbol