i am really confused about some thing, and as i searched every thing is ok in my coding !
here when i use this code
sOutput.writeObject(theuser);
sOutput.writeObject(thepass);
sOutput.writeObject(thename);
sOutput.writeObject(themail);
sOutput.writeObject(thephone);
and recieve with this
String theuser = (String) sInput.readObject();
display(theuser);
String thepass = (String) sInput.readObject();
display(thepass);
String thename = (String) sInput.readObject();
display(thename);
String themail = (String) sInput.readObject();
display(themail);
String thephone = (String) sInput.readObject();
display(thephone);
everything works fine, but when i add these to the ready and write
int RID = (int) sInput.readInt();
to the read and
sOutput.writeInt(RID);
to the write
then it throws no exception, no error, just my server stops there at reading it ! RID is defined Int in sender ,its been given a random number. can you please help me?
When the reading program is stuck waiting for the input, and you know for sure that the writing program writes the data to its output, it is often the case that this happens because the written data has been buffered. In other words, it's been placed in a holding location on the sender, and not put on the wire to be sent to the receiver.
A simple way to fix this is to call flush() after writing the last element of data, like this:
sOutput.writeInt(RID);
sOutput.flush();
Related
I've got a fairly simple multi-thread chat program, where a server receives data from multiple clients and is then supposed to relay the messages back to all clients.
While the server does receive all its data properly, I can't seem to make the clients receive the returned values.
I've read through plenty of code and suggestions from both StackOverflow and other forums, but I can't seem to find the issue.
The ServerThread has the PrintWriter "out", declared and grabbed as such:
private PrintWriter out;
public PrintWriter getWriter(){
return out;
}
public void run() {
try{
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
This method in the ServerThread is supposed to pass the data along:
if(input != null){
//Loggs message to file:
loggMessage(input);
//Loggs message to Server GUI
setOutput(input);
//Prints message to Output
System.out.println(input);
//Sends message to other clients:
for(ServerThread c : UserList){
System.out.println("Client discovered");
PrintWriter clientwriter = c.getWriter();
clientwriter.write(input);
System.out.print(input + " <-- was written to client");
}
}
The console (and file) get all messages as expected, but the clients don't. This is, as far as I can tell, either caused by something being off with that line in this batch of code, or something being wrong clientside
Clientside:
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
The "in" is declared like that, a few rows before the following chunk of code:
if(in.ready()){
String serverin = in.readLine();
System.out.println(serverin);
setOutput(serverin);
}
This system.out.print doesn't print anything. This makes me believe that something is wrong already at the if, but I'm not sure what that would be.
So, the clients won't receive the messages, and I'm not sure why.
When the program is run, the server indicates that all clients have been found and messages appropriately, yet they won't receive anything.
Any ideas?
I think that this call to in.ready() is wrong.
if(in.ready()){
String serverin = in.readLine();
System.out.println(serverin);
setOutput(serverin);
}
There is no need to call ready() because in.readline() will wait(block) until there is input.
An other issue is that readline() will wait(block) until the server send a newline, and only return the string once it gets a newline so are you sure that input contains a newline?
So, after quite a lot of testing and comparing code, I've finally found the issue.
The "clientwriter.write(input)" should have been "clientwriter.println(input)". After changing that the whole system worked as intended.
I have wrote an event listener that suppose to read any messages of a specific type from a receiver.
here is my event listener:
class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR() && event.getEventValue() > 0) {
try {
byte[] buffer = SP.readBytes(6);
String type = new String(buffer);
if (type.equals("$GPGGA")){
String line = "";
line = line + type;
buffer = SP.readBytes(66);
String values = new String(buffer);
line = line + values;
writer.write(line + "\n");
}
}
catch (SerialPortException ex) {System.out.println(ex);}
catch (IOException ex) {System.out.println(ex);}
}
}
}
right now after i check that the message is of the correct type i just read 80 bytes off data, which is roughly the size of the message.
however, sometimes the message is not full and there for it is shorter then usual.
this is the message structure:
as you can see, the message end s with <CR><FL>.
i would like to modify my method so it would read each byte at a time and stop reading once it hits the end of the message. how can i catch the <CR><FL> inside the byte array?
any help would be appreciated. thank you.
It depends on the definition of "messages": are they fixed-length or delimited by a certain sequence? In your current code, you're reading a "header" that is 6 bytes long and a "message" that is 66 bytes long. However, it appears that you actually don't know the length a priori, and instead the message is newline-terminated. A couple of pointers:
You're reading bytes from the stream, then turning them into a String by using the String(byte[]) ctor. The documentation states that this uses the default charset for your platform, which may be UTF-8, Latin-1 or whatever regional default. If you are communicating with a device over a serial port, this is probably not what you want since the device is likely to have a single, specific charset for messages (maybe ASCII?). Investigate that point and use either this String ctor or, if you want to be notified when the input contains undecodable garbage, the CharsetDecoder class.
If the messages are text-based and newline-delimited, you should definitely use a BufferedReader to read from the stream. Assuming that your SP serial port is an InputStream, you could create a BufferedReader over it, and then call the readLine() method on the reader. The reader will keep requesting bytes from the stream until it sees a newline, then return the whole line to you as a String. Reader objects also encapsulate the Charset I was talking about before.
I have managed to solve my problem.
pretty easy solution:
String tmp = SP.readString();
String[] msgs = tmp.split("\r\n");
after reading the string from the serial port, i just split it by the end of line.
I've been making a instant chat program, and wanted to make it possible for users to "whisper" or private message one another. The way I implemented that is the user would type:
/w [username] [message]
I then send it to the server which sends it to all the users. The users then have to check to see if its sent to them, this is that method:
if (message.startsWith("/msg/")) {
message = message.trim();
message = message.substring(5);
String[] words = message.split("//s");
String UserName = null;
try {
String username = words[2];
UserName = username;
System.out.println(UserName);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error reading the whisper command!");
}
if (UserName == client.getName()) {
List<String> list = new ArrayList<String>(Arrays.asList(words));
list.removeAll(Arrays.asList(2));
words = list.toArray(words);
String text = words.toString();
text = "You've been whispered! " + message;
console(text);
}
Everytime I send a /w when I'm testing it always give the ArrayIndexOutOfBoundsException. I also modify the message in the sending. Heres that method:
else if (message.toLowerCase().startsWith("/w")) {
message = "/msg/" + client.getName() + message;
message = "/m/" + message + "/e/";
txtMessage.setText("");
}
I also added a whole bunch more options for the actual code for the users, I made it /whisper, /m, /msg, and /message, but those are all just copies of this with a different input. Why is it giving me an ArrayIndextOutOfBoundsException, when the 3rd place in the words array SHOULD be the username that the sender is trying to send it to. Obviously this probably isn't the best way to send private messages, and if any of you guys have a simpler way I can implement to my server, please go ahead and let me know! Just know that I am a young, new programmer and so I will probably have a lot of questions.
The slashes in your split() regex are backwards. You need
String[] words = message.split("\\s");
You can also just use a space
String[] words = message.split(" ");
I'm getting this really annoying error. I've been working on it for days, as well as extreme amounts of research with no success. Basically, what the code is doing, is it reads the file, but it seems to remove the text after reading it. And only certain lines. This is my Reader method:
synchronized public static String getValue(String path, String filename, Boolean useColors, String folder){
try{
while(!TxtWriter.isResting());
FileRequest req = writer.getRelitive(filename, path);
if(req==null){
File f = new File(Conquest.FilePaths+"/"+folder, filename);
if(!f.getParentFile().exists())f.getParentFile().mkdirs();
if(f.exists()){
BufferedReader in = new BufferedReader(new FileReader(f));
String a;
while((a=in.readLine())!=null){
if(a.startsWith("'"+path+"'"+":")){
in.close();
a=a.substring(path.length()+3);
if(useColors)a=colorCoder(a);
return a;
}
}
in.close();
}else TxtWriter.createFile(filename, folder);
}else return ((useColors)?colorCoder(req.getMessage()):req.getMessage());
}catch(Exception e){
System.err.println("[Conquest/TxtReader] Error reading file "+filename+"!");
e.printStackTrace();
}
return null;
}
This is the file before reading:
'Kingdom':Devonel
'Flags':Leader
I call the method
public String getPlayerKingdom(String p){
String in = TxtReader.getValue("Kingdom", p+".txt", false, "Citizens");
return ((in==null)?in:"None");
}
It returns "None", and the file now just has 'Flags':Leader, and nothing else.
What really puzzles me and certain methods work, while other don't. Even when they are exactly the same code, but with different strings. This method right here is the same thing, but works just as its supposed to.
public int getResource(String kingdom, String name){
String out = TxtReader.getValue("R-" + name, kingdom + ".txt", false, "Kingdoms");
if(out==null)return 0;
return Integer.valueOf(out);
}
If anyone could help, I'd be thankful. :)
This line looks wrong:
return ((in==null)?in:"None");
Shouldn't it be the other way around?
return ((in==null)?"None":in);
I'm not a fan of the ternary operator construct for this very reason. Just use an if/else block and be clear about what you're doing.
Also, a BufferedReader will not remove information from a File. Period. It just reads in information and nothing else. If a line is being deleted, there's likely another bug in your program, possibly in code not shown that is causing this.
But regardless of the source of your error, your code looks very inefficient and error-prone. Why are you trying to re-read the File each time you need to check for a match? Why not simply read the file in once, and then store the information in a HashMap<String, String>?
Yesterday i posted a question about a problem i had concerning inputstream reading and i was helped.
I find myself in similar situation but this time i know that I am doing the right thing but yet it is not working for me.
I am reading from an inputstream but i get different value. No matter how i change the data i send i get the same string ("toForklift-42") as the value. At first i prefix the value i send with "toForklift-" but i have changed that string to different strings yet i get the same string in the bracket. i Even changed the number 42 to a different number but yet when i run the program, i get the same string in the console. Below is what am sending : as
Two classes for sending and receiving.
Am using the leJOS NXJ NXTConnector to make the connection and open the streams.
// sender class
class PanButton implements Runnable {
DataInputStream dis;
DataOutputStream dos;
TouchSensor touch = new TouchSensor(SensorPort.S4);
PanicButtonCrossing(DataInputStream is, DataOutputStream os) {
dos = os;
dis = is;
}
public void run() {
while (!touch.isPressed()) {}
// If you get a message: KILL EVERYTHING
Motor.A.stop();
Motor.B.stop();
Motor.C.stop();
try { // send 42
int value = 42;
dos.writeChars("ggggggggg" + 455 + "\n");
dos.flush();
Sound.systemSound(true, 3);
} catch (IOException ioe) {
LCD.drawString("Write Exception", 0, 0);
}
System.exit(1);
}
// Reader classs
public class InputReaderCrossing implements Runnable{
private DataInputStream dataIn;
private DataOutputStream dataOut;
public InputReaderCrossing(DataInputStream dataIn, DataOutputStream dataOut) {
this.dataIn = dataIn;
this.dataOut = dataOut;
this.sensor = sensor;
this.readLock = new Object();
}
public void run(){
while(true){
String dataFromCrossing1 = readLineFromCrossing();
System.out.println("CROSSING VALUE: " + dataFromCrossing1 + " :VALUEEEEE");
}
}
private String readLineFromCrossing() throws IOException{
StringBuffer sb = new StringBuffer();
synchronized(readLock){
while(true) {
char c = this.dataIn.readChar();
if (c == '\n') break;
sb.append(c);
}
return sb.toString();
}
}
}
I need your help please. i have spent 6 hours but can't find the the reason. I don't understand no matter what i send i get "toForklift-42".
At first i tried to send the 42 with the writeInt() methods but then on the reader class side i use readInt() but i get somethings like:
745687894
459877455
456987456
So i changed to the string to find out why and lo and behold i get that string no matter what i send. it is like that string is fixed in the input stream and nothing is sent. I don't know what is happening.
Need help
This is a very confusing question. We don't really know which process is writing which data, and how it's being transmitted, and which process is picking it up. There's some relevant code to see here, but I didn't see enough to tell the story. How did dataFromCrossing1 get its value?
I think it would do good to organize your problem in such a way that you can ask an outsider a question about it. Possibly in the process of doing so you could stumble on the solution yourself.
In principle, if you are changing string constants in your program yet you continue to see the same output, then what's happening is that
The original program is still running; or
all versions since the original have had errors, so the class files you once compiled successfully are running again and again; or
you're not really running the program you think you're running.