I'm trying to make a Java TCP client and a node.js TCP server talk together.
This is my code at the moment :
The Java client
import java.net.;
import java.io.;
public class Client2{
public static void main(String[] args) throws Exception{
Socket s = new Socket("192.168.1.35",8500);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF("abcdefgh");
dos.close();
s.close();
}
}
the Node.js Server
var net = require('net'),
server = net.createServer();
server.on('connection', function (client) {
console.log('Hello World !');
client.on('data', function(data) {
var message = data.toString('utf8');
console.log('***' + message +'***');
});
});
server.listen(8500);
This example will give this result back :
Hello World !
**abcdefgh***
but with this as input :
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
it gives this back :
Hello World !
***�abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz***
with this input :
qq32we3w87d 38s1d87s4df7s4d1+s2d7f+sfdsf4sà$àà3663%ç%&ç%&ç
it gives this back :
Hello World !
***#qq32we3w87d 38s1d87s4df7s4d1+s2d7f+sfdsf4sà$àà3663%ç%&ç%&ç***
tldr: Sometimes when logging the buffers, node adds characters (rectangles with numbers or ?) at the beginning or event cuts some characters at the start out.
- How can I log buffers and assign them to a variable the right way ?
I'm not an expert on DataOutputStream, but if it really is adding extra characters, you should use something else.
When I did server stuff, I used BufferedReader and BufferedWriter. It looks like this:
Socket s = new Socket(<<WEB ADDRESS AS STRING>>,<<PORT NO AS INT>>);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//left out a bunch of lines. This is where you should read the lines
//of input (with an inner loop) and send stuff back
s.shutdownInput();
bw.flush();
s.shutdownOutput();
NOTE, IF YOU'RE GOING TO DEAL WITH LARGE PAGES, THIS COULD CAUSE A PROBLEM, AS THE BUFFEREDREADER AND BUFFEREDWRITER WILL FILL UP BEFORE YOU'RE READY. if this is a problem I'd look into the other Reader and Writer classes. They are quite plentiful, as I understand it, and one should suit your needs.
Related
I am coding a function which will check if file CQ.txt exists and if so, read from it. I have been having an issue where I have declared a printwriter outside of the while loop. Later in the application, it is supposed to write Question 1: correct or Question 2: correct to the file.
But, it does not. It creates the text file but when I check it, it shows up as empty.
Here is the code, thank you in advance:
package receiverhost;
import java.io.*;
import java.net.*;
public class ReceiverHost {
public static void main(String[] args) throws Exception {
//set up socket on port 5000
ServerSocket Server = new ServerSocket(5000);
//set up "cookie"/ text file to be written to/ read from eventually
Writer DB = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("CQ.txt"), "utf-8"));
System.out.println("TCPServer Waiting for client on port 5000");
while(true){
//declare string fromclient
String fromclient;
Socket connected = Server.accept();
System.out.println(" The client" + " " + connected.getInetAddress() + ":" + connected.getPort() + " is connected ");
//read/ retrieve client output stream
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connected.getInputStream()));
fromclient = inFromClient.readLine();
if(fromclient.equals("Q1C")){
//write to CQ.txt
DB.write("Q1: correct");
}
if(fromclient.equals("Q2C")){
//write to CQ.txt
DB.write("Q2: correct");
}
}
}
}
You should call 'write' method on BufferedWriter, and later 'close' it. Here is an example:
How to Write text file Java
BufferedWriter as the name suggests buffers the write to file. Any write to BufferedWriter will be written to in memory buffers not to the file directly.
this is done for efficiency purposes and in order to save CPU time wasted for IO .
Each time you invoke bufferedWriter.write it appends the data to buffer, writes the buffer data to file only if Buffer croses the threshold , either default or supplied by BufferedWriter(FileWriter,BufferSize) constructor .
It is recomended to flush the writer and close it after you have all the data written to bufferedWriter.
ideally a sample code would look like
Writer DB = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("CQ.txt"), "utf-8"));
DB.write("Dummy Data1 ");
DB.write("Dummy Data2");
DB.flush();
DB.close();
after close and flush you should be able to see all your data in the file.
As I mentioned in the title my problem is the following: I would like to send a string array in C# using sockets to a Java application which also uses sockets. I have tried to send the first and the second item of the array but when I tried to add them to an array in the Java app, the two item sticked together so I couldn't handle them as items of an array. I'm new in socket programming, so please help me how can I receive and handle the sent array in the Java app and maybe how to send them in the C# app correctly.
Thank you for your help!
Regrads, Stanley.
EDIT:
The connecting parts are OK so I just post the sending parts.
Probably not too professional because I was just trying:
Server:
String[] texts = new String[2];
texts[0] = "hello";
texts[1] = "world";
for (int i = 0; i < texts.Length; i++)
{
buffer = Encoding.UTF8.GetBytes(texts[i].ToCharArray(), 0, texts[i].Length);
nwStream.Write(buffer, 0, texts[i].Length);
}
Client: (and this is where I'm not too confident)
ArrayList<String> texts = new ArrayList<String>();
BufferedReader in;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
texts.add(0, in.readLine());
Maybe it's beacuse of the readLine but I'm not sure.
Really this is more about how you serialize and deserialize than it is about sockets itself. The hard part, connecting to a socket and sending/receiving data is taken care of.
You have to decide on the format of your data. That isn't done for you. In your case, you can use a simple line terminator like '\n' to separate the lines of data for you. On the C# side, your formatting code would look like this:
// assumption: socket is your C# socket
using(NetworkStream str = new NetworkStream(socket))
using(StreamWriter writer = new StreamWriter(str))
{
foreach (string line in arrayOfStrings)
{
// This automatically appends a new line character to the end
// of the line
writer.WriteLine(line);
}
}
On the Java side you would use a similar construct. In Java, the equivalent to a StreamReader would be a BufferedReader.
// socket is your Java socket object
InputStreamReader charReader = new InputStreamReader(socket.getInputStream());
BufferedReader lineReader = new BufferedReader(charReader);
String line;
ArrayList<String> lines = new ArrayList<String>();
// readLine() reads to the first new line character or end of file
// and returns the string up to that point
while ((line = lineReader.readLine()) != null)
{
lines.add(line);
}
// Converting to an array of strings is simple Java from here:
String[] arrayOfLines = lines.ToArray(new String[lines.size()]);
Of course things can get slightly more complicated if you want to use JSON, or some other means of sending formatted data. Thankfully both Java and C# have reliable a reliably serializer/deserializer library for those standard formats.
Can I share an InputStream or OutputStream?
For example, let's say I first have:
DataInputStream incoming = new DataInputStream(socket.getInputStream()));
...incoming being an object variable. Later on I temporarily do:
BufferedReader dataReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
I understand that the stream is concrete and reading from it will consume its input, no matter from where it's done... But after doing the above, can I still access both incoming and dataReader simultaneously or is the InputStream just connected to ONE object and therefore incoming loses its input once I declare dataReader? I understand that if I close the dataReader then I will close the socket as well and I will refrain from this but I'm wondering whether I need to "reclaim" the InputStream somehow to incoming after having "transferred" it to dataReader? Do I have to do:
incoming = new DataInputStream(socket.getInputStream());
again after this whole operation?
You are using a teaspoon and a shovel to move dirt from a hole.
I understand that the stream is concrete and reading from it will
consume its input, no matter from where it's done
Correct. The teaspoon and shovel both move dirt from the hole. If you are removing dirt asynchronously (i.e. concurrently) you could get into fights about who has what dirt - so use concurrent construct to provide mutually exclusive access. If access is not concurrent, in other words ...
1) move one or more teaspoons of dirt from the hole
2) move one or more shovels of dirt from the hole
3) move one or more teaspoons of dirt from the hole
...
No problem. Teaspoon and shovel both remove dirt. But once dirt gets removed, it's removed, they do not get the same dirt. Hope this helps. Let's start shovelling, I'll use the teaspoon. :)
As fast-reflexes found, be very careful about sharing streams, particularly buffered readers since they can gobble up a lot more bytes off the stream than they need, so when you go back to your other input stream (or reader) it may look like a whole bunch of bytes have been skipped.
Proof you can read from same input stream:
import java.io.*;
public class w {
public static void main(String[] args) throws Exception {
InputStream input = new FileInputStream("myfile.txt");
DataInputStream b = new DataInputStream(input);
int data, count = 0;
// read first 20 characters with DataInputStream
while ((data = b.read()) != -1 && ++count < 20) {
System.out.print((char) data);
}
// if prematurely interrupted because of count
// then spit out last char grabbed
if (data != -1)
System.out.print((char) data);
// read remainder of file with underlying InputStream
while ((data = input.read()) != -1) {
System.out.print((char) data);
}
b.close();
}
}
Input file:
hello OP
this is
a file
with some basic text
to see how this
works when moving dirt
from a hole with a teaspoon
and a shovel
Output:
hello OP
this is
a file
with some basic text
to see how this
works when moving dirt
from a hole with a teaspoon
and a shovel
Proof to show BufferedReader is NOT gauranteed to work as it gobbles up lots of chars from the stream:
import java.io.*;
public class w {
public static void main(String[] args) throws Exception {
InputStream input = new FileInputStream("myfile.txt");
BufferedReader b = new BufferedReader(new InputStreamReader(input));
// read three lines with BufferedReader
String line;
for (int i = 0; (line = b.readLine()) != null && i < 3; ++i) {
System.out.println(line);
}
// read remainder of file with underlying InputStream
int data;
while ((data = input.read()) != -1) {
System.out.print((char) data);
}
b.close();
}
}
Input file (same as above):
hello OP
this is
a file
with some basic text
to see how this
works when moving dirt
from a hole with a teaspoon
and a shovel
Output:
hello OP
this is
a file
This will be disastrous. Both streams will have corrupted data. How could Java possibly know which data to send to which Stream?
If you need to do two different things with the same data, you're better off storing it somewhere (possibly copying it into two Queue<String>), and then reading it that way.
Ok, I solved this myself.. interesting links:
http://www.coderanch.com/t/276168//java/InputStream-multiple-Readers
Multiple readers for InputStream in Java
Basically... the InputStream can be connected to multiple objects reading from it and consuming it. However, a BufferedReader reads ahead, so when involving one of those, it might be a good idea to implement some sort of signal when you're switching from for example a BufferedReader to a DataInputStream (that is you want to use the DataInputStream to process the InputStream all of a sudden instead of the BufferedReader). Therefore I stop sending data to the InputStream once I know that all data has been sent that is for the BufferedReader to handle. After this, I wait for the other part to process what it should with the BufferedReader. It then sends a signal to show that it's ready for new input. The sending part should be blocking until it receives the signal input and then it can start sending data again. If I don't use the BufferedReader after this point, it won't have a chance to buffer up all the input and "steal" it from the DataInputStream and everything works very well :) But be careful, one read operation from the BufferedReader and you will be back in the same situation... Good to know!
java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(is));
String cmd=null;
while(is.available()<1){}
cmd = br.readLine();
System.out.println("cmd: "+cmd);
if(cmd.equals("search")){
String[] param = br.readLine().split(",");
for(String s:param){
System.out.println(s);
}
this the client code which accepts a string sent by server.but an exception is thrown in the line cmd=br.readLine()... a connection reset error..
server code is
Socket(InetAddress.getLocalHost(),1234);
OutputStream os = s.getOutputStream();InputStream is=s.getInputStream();
java.io.BufferedWriter bw=new java.io.BufferedWriter(new java.io.OutputStreamWriter(os));
String ss="search";
bw.println(ss);
bw.flush();
System.out.println("search cmded");
String param = "a,*,0,-1";
bw.println(param);
bw.flush();
System.out.println("param sent");
i've tried using print writer and the bufferedwriter but nothing is working correctly
so what could be the possible solution ???
also one thing worth mentioning is im using a listener service which creates a new server code mentioned above to handle particular client requests...
so wot could be soln now ??
In the server, your BufferedWriter is named bw but you're writing to pw.
Get rid of the available() test. You have it back to front, and it's not valid anyway. readLine() will block while there is no data. Just test the return value of readLine() for null, and break.
I have a program to pull the source code of a webpage and save it to a .txt file. It works if done with just one at a time, but when I go through a loop of say 100 pages all of a sudden each page source starts to get cut off between 1/4 and 3/4 of the way through (seems to be arbitrary). Any ideas on why or how I would go about solving this?
Initial thoughts where that the loop is going too fast for the java (I am running this java from a php script) but then thought that it technically shouldn't be going to the next item until the current condition was finished anyway.
Here is the code I'm using:
import java.io.*;
import java.net.URL;
public class selectout {
public static BufferedReader read(String url) throws Exception{
return new BufferedReader(
new InputStreamReader(
new URL(url).openStream()));}
public static void main (String[] args) throws Exception{
BufferedReader reader = read(args[0]);
String line = reader.readLine();
String thenum = args[1];
FileWriter fstream = new FileWriter(thenum+".txt");
BufferedWriter out = new BufferedWriter(fstream);
while (line != null) {
out.write(line);
out.newLine();
//System.out.println(line);
line = reader.readLine(); }}
}
The PHP is a basic mysql_query while(fetch_assoc) grab the url from the database, then run system("java -jar crawl.jar $url $filename");
Then, it fopen and fread the new file, and finally saves the source to database (after escaping_strings and such).
You need to close your output streams after you finish writing each file. After your while loop, call out.close(); and fstream.close();
You must flush the stream and close it.
finally{ //Error handling ignored in my example
fstream.flush();
fstream.close();
}