I have a simple socket client written in netty.io and for data sending and receiving I use SimpleChannelInboundHandler. and in Initializer class I defined this:
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
but in this way I need every time put "\n" new line symbol at the end of string which I needn't. without this symbol I can't send or receive any string data. what is the solution use string data in netty without new line delimiter?
You can specify whatever delimiter you like, for instance
ByteBuf[] delimiters = new ByteBuf[] {
Unpooled.wrappedBuffer(new byte[] { '\r', '\n' }), // WINDOWS
Unpooled.wrappedBuffer(new byte[] { '\n' }), // UNIX / OSX
Unpooled.wrappedBuffer(new byte[] { '\r' }) // LEGACY MAC
};
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(MAXFRAMELENGTH, delimiters));
In this way, if you omit it, you can get rid of \n and replace with another character.
If you want to omit any delimiter, than I think you could use a FixedLengthFrameDecoder:
pipeline.addLast("framer", new FixedLengthFrameDecoder(yourFrameLength));
or a LengthFieldBasedFrameDecoder for more options.
Related
I need to store an error message in a string after the error has occurred. I am unable to use the try and catch blocks as the error will appear after the initial code is run.
Before I was using the code below to store the error message in a file when it appeared:
PrintStream printS = new PrintStream("file.txt");
System.setErr(pst);
However I want to store it and a string and send this string else where after the error occured. I have tried already using a byte array output stream:
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
PrintStream printS = new PrintStream(byteArray);
System.setErr(pst);
String tester = byteArray.toString(StandardCharsets.UTF_8);
But when I try to print the string it is empty and does not contain the error. Does anyone know how I can run code after a error has occurred, so I can send this error message elsewhere?
Java just runs code on the spot, you're not defining triggers for the future. You are creating a new empty byte array output stream, setting it up as 'target' for any System.err calls later, and then immediately turning it into a string. It's still blank at this point, of course.
What you want is quite complicated - you'd have to write a custom PrintStream that saves anything sent to it, until it 'sees' a newline and then acts. Something like:
OutputStream myCustomReportingStream = new OutputStream() {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
#Override public void write(int b) {
if (b == '\r') continue;
if (b == '\n') {
process(new String(buffer.getBytes(), StandardCharsets.UTF_8));
buffer.reset();
} else {
buffer.write(b);
}
}
private void process(String message) {
// YOUR CODE HERE
}
};
System.setErr(new PrintStream(myCustomreportingStream, true, StandardCharsets.UTF_8));
A bunch of things are happening here:
We're defining a custom OutputStream which buffers everything sent to it, until it sees \n (which is "newline" in ASCII, UTF-8, and many other encodings), at which point it turns the buffer into a string, sends that string to the process method, and clears out the buffer. It also ignores \r to deal with \r\n which is windows-style newlines.
We then use that OutputStream as basis for a new PrintStream, and then set up syserr to use this printstream.
This code does not deal with anything that sends data to System.err but doesn't send a newline symbol.
Anytime anybody anywhere runs System.err.println, your process() method will be run.
It appears to me like JMS TextMessage containing Java.lang.String isn't recognizing \r\n as line-break but instead treating the CR LF as part of input on a Windows machine.
#Override
public void onMessage(Message message) {
try {
String text = ((TextMessage)message).getText();
String line=null;
BufferedReader br = new BufferedReader(new StringReader(text));
for(line = br.readLine(); line != null; line = br.readLine()) {
System.out.println(line);
}
catch (JMSException e) {
System.err.println( "Error processing message: " + e.getMessage() );
e.printStackTrace();
}
Can anyone provide any input and /or recommednations around the same.
It's not completely clear from your question, but it sounds like the string is read correctly on input, but it is not being formatted correctly by the println output.
Control characters like line-feeds and and carriage returns are just like any other character in a string. What makes them different is how they are interpreted by the output device, lie a terminal program (e.g. linux terminal, putty, etc.) or the windows command prompt.
If you are printing this string to a destination that does not interpret these characters correctly, you may not see proper formatting even if the string data is correct. For example some IDE's output windows do not correctly format certain control characters, so you'll see different formatting in your IDE than you would see in an actual terminal.
One possible reason could be that it is not sent properly from the source system. I would look there to see what can be done next. Most languages offer cross-platform EOL constant's which might come in handy. For instance, Ruby has four:
irb(main):002:0> require 'English'; test = "One"+ $INPUT_RECORD_SEPARATOR
=> "One\n"
irb(main):003:0> test1 = "One" + $/
=> "One\n"
irb(main):004:0> test2 = "One"+$-0
=> "One\n"
irb(main):005:0> require 'English';test3="One"+$RS
=> "One\n"
irb(main):006:0>
You can try this:
String text = ((TextMessage)message).getText();
if(text!=null)
text=text.replaceAll("\r\n","");
I am creating a chat application in Java. User can send multiple new lines in a single message. Previously, I was not allowing the user to send new lines. So it was easy to use new line character as End OF Message. But now I am allowing the user to send new lines in a message. What character/string should I use to mark the end of the message.
You can easily avoid end of message by adding extra 4 byte. First 4 byte represent length of your message. Then add full message.
Sample sender code:
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
String msg = "its a test message";
byte[] byteMsg = msg.getBytes();
int length = byteMsg.length;
byte[] lengthByte = ByteBuffer.allocate(4).putInt(length).array();
byte[] finalMsg = new byte[length+4];
System.arraycopy(lengthByte, 0, finalMsg, 0, 4);
System.arraycopy(byteMsg, 0, finalMsg, 4, length);
bufferedOutputStream.write(finalMsg);
When you read your message then read first 4 byte. Convert this 4 byte to integer. This is your incoming message length. Then parse those byte.
It's your application so you're free to use whatever you like, including EOF and NUL characters suggested by Marko and KDM.
Just make sure it's a character your users won't be using in their messages.
I'm trying to get a very simple Client-Server system to work, where the Client will send a String over to the Server, and the server will then store that String into a file.
The client sends the string through:
//Other Code
sockStrm = new DataOutputStream (clientSocket.getOutputStream ());
//Other code
sockStrm.writeChars (line);
//Other code
And the Server receives the String with:
//Other code
strm = new BufferedReader (new InputStreamReader (clientSocket.getInputStream ()));
//Other code
stringLine = strm.readLine ();
//Other code
When I send the string STOP, the length of the String is 4 on the client side, and on the server side the length of the String is 9 and displays as STOP
I've tried to substring the received String on the Server side, without luck.
Any pointers on how to deal with this?
Use symmetric methods:
DataOutputStream sockStrm =...
sockStrm.writeUTF(str);
and
DataInputStream sockStrm = ...
String str = sockStrm.readUTF();
writeChars writes individual characters as two byte values. Readers follow the encoding to reconstruct the string from a sequence of bytes, which will definitely not be according to high-byte-low-byte for each character code. Hence you get some mish-mash of zero bytes with the original low-byte values so you still have a glimpse of the original string value.
Using \x00 to denote a NULL byte:
S-T-O-P => on the line: \x00-S-\x00-T-\x00-O-\x00-P => prints as STOP
Use a loop over the characters of the incoming string and display their integer values (str.charAt(i)) to see the above for yourself.
So I am creating an application using sockets. And I have the client who sends a message and it passes to the server using writeObject(new String("Name|Message"));.
And I read the message in the server using readObject();
I am trying to pass this string object to an array. But I get [Ljava.lang.String;#6bb9ae1a.
Here is what I am trying:
ObjectInputStream saida = new ObjectInputStream(client.getInputStream());
String[] read = saida.readObject().toString().split("|");
System.out.println(read);
I tried also to make variables for each split:
String readm = read[1];
String readn = read[0];
But it returns me "" as the name and "A" as the message (?)
Ow, and the socket is working, because if I do (String) saida.readObject(); it returns me the normal string.
use like that :
saida.readObject().toString().split("\\|");
and then
String readm = read[1];
String readn = read[0];
Because pipe symbol is the special character and splitting special chars is different. And you cannot use systemoutprintln to print the string array.