I have socket listen on Dart, that receives messages from server (written on C).
Client (Dart):
(Uint8List data) async {
Future.delayed(const Duration(seconds: 1));
String serverResponse = String.fromCharCodes(data);
globals.progressEvent = double.parse(serverResponse));
}
Server(C):
send(client_fd, "90", BUFFER_LENGTH, 0);
When run it, I see an exception "Unhandled Exception: FormatException: Invalid double"
it fails on line "double.parse(serverResponse))"
What can be the reason?
Check String parser
As the commenter suggested, I'd recommend checking whether the String you get in Dart corresponds to what the server sends. Have you tried printing it to take a look?
Additionally, I'd generally advise you to use double.tryparse, which will not throw an exception, but instead return null when parsing fails. You can then see if it's null, and if so print some debugging information.
Encoding
I'm not too familiar with how Dart handles binary data, but to me it looks like you use 1 byte for each character (UTF-8), whereas Dart's fromCharCodes seems to conventionally use the UTF-16 format, with 2 bytes per character. When trying to parse your 9 and 0 together, I guess it gets a non-numeric value, causing the parser to faill. https://api.flutter.dev/flutter/dart-core/String/String.fromCharCodes.html
Related
I've been trying to mount a custom protocol over the TCP module on the NodeMCU platform. However, the protocol I try to embed inside the TCP data segment is binary, not ASCII-based(like HTTP for example), so sometimes it contains a NULL char (byte 0x00) ending the C string inside the TCP module implementation, causing that part of the message inside the packet get lost.
-- server listens on 80, if data received, print data to console and send "hello world" back to caller
-- 30s time out for a inactive client
sv = net.createServer(net.TCP, 30)
function receiver(sck, data)
print(data)
sck:close()
end
if sv then
sv:listen(80, function(conn)
conn:on("receive", receiver)
conn:send("hello world")
end)
end
*This is a simple example which, as you can see, the 'receiver' variable is a callback function which prints the data from the TCP segment retrieved by the listener.
How can this be fixed? is there a way to circumvent this using the NodeMCU library? Or do I have to implement another TCP module or modify the current one's implementation to support arrays or tables as a return value instead of using strings?
Any suggestion is appreciated.
The data you receive in the callback should not be truncated. You can check this for yourself by altering the code as follows:
function receiver(sck, data)
print("Len: " .. #data)
print(data)
sck:close()
end
You will observe, that, while the data is indeed only printed up to the first zero byte (by the print()-function), the whole data is present in the LUA-String data and you can process it properly with 8-bit-safe (and zerobyte-safe) methods.
While it should be easy to modify the print()-function to also be zerobyte-safe, I do not consider this as a bug, since the print function is meant for texts. If you want to write binary data to serial, use uart.write(), i.e.
uart.write(0, data)
I am new to ADF. Please help. Pasting a snippet of my code:-
I am unable to print a new line message with \n.
<af:message id="errMessage" message="#{backingBeanScope.ta_del_entUiBean.errorMessage}" messageType="error"
visible="#{backingBeanScope.ta_del_entUiBean.error}"/>
public String getErrorMessage()
{
return message;
}
message contains a String this way, say : The following error have occurred. \n 1. Null ponter exception. \n 2. ODBC Exception \n. 3. JDBC Exception
The output is .
The following error have occurred. 1. Null ponter exception. 2. ODBC Exception . 3. JDBC Exception
How do I make it appear as
The following error have occurred.
1. Null ponter exception.
2. ODBC Exception
3. JDBC Exception
Thanks a lot for the help. The Java Platform version is 1.7.0_51 and the `Jdev` version is 12.1.3.0
I had the same issue. But our client was using IE browser. It works well in IE browser.
The problem with the af:message or af:messages components is that they firstly get rendered on the page, and after that, the content will be attached. That's why when you insert a text containing special characters like "\n" or "\r" they will be printed as they are (actually, they are know only to the compiler who knows how to parse them, but remember, you are using an ADF faces component, not the standard output like in the case of System.out.println() ).
With this in mind, it should be clear that you have to instruct the browser how to print the content. How? Easy, just by inserting HTML tags inside your message body. In your case, the message String should be:
<html><body>
The following error have occurred.<br/>
1. Null ponter exception.<br/>
2. ODBC Exception<br/>
3. JDBC Exception<br/>
</body></html>
Or you can enclose the lines within a paragraph tag instead ( < p > ).
I am writing a program to communicate via RS232 from the PC to a microchip.
I am use to C#, but I started using Visual C++.
I get the following error:
IntelliSense: no instance of overloaded function "System::IO::Ports::SerialPort::Write" matches the argument list argument types are: (RTC_Visual::uint8 [27U], int,RTC_Visual::uint8)
I wrote the command to write to the serial port as follows:
serialPort1->Write(TxStruct.u8_Buffer, 0, TxStruct.Message.u8_Length);
please can someone tell me what am I doing wrong and or what is the correct structure for the serialport->write method.
thanks in advance
Not very clear from your question; showing a bit of code would help.
Seems that the parameter TxStruct.u8_Buffer does not match either the expected Byte[] or Char[]
I imply by the dot (.) that TxStruct is not managed?
The following works:
SerialPort ^myport=gcnew SerialPort;
//configures the port --ptr is a class that interacts with the user
myport->PortName="COM"+ptr->getportnumber();
myport->BaudRate=ptr->getbauds();
myport->DataBits=ptr->getdatab();
myport->StopBits=ptr->getstopb();
myport->Parity=ptr->getparity();
myport->WriteBufferSize=4096;
myport->RtsEnable=false;
myport->ReceivedBytesThreshold=256;
myport->WriteTimeout = 500;
String^ datatowrite="Data to write";
array<Byte>^ mybytes= Encoding::UTF8->GetBytes(datatowrite);
try
{
myport->Open();
myport->Write(mybytes,0,mybytes->Length);
}
catch (Exception^ e)
{
//error
MessageBox::Show( e->Message, "Port Error",
MessageBoxButtons::OK, MessageBoxIcon::Exclamation );
}
The above encodes to UTF8 as I deduct from the parameter TxStruct.u8_Buffer.
Beware of the length of the buffer you are using and the WriteBufferSize property of the serial port. Also, a too long buffer with a handshake XonXoff might result in a timeout exception.
Hope this helps.
All the best,
Adan
I know I'm not supposed to access a control from a thread that didn't create it, but I tried it anyway and got a really peculiar error. I did it in assembly, which everybody hates reading, so here's the equivalent code in C:
/* Function that returns the number of characters after startOfItem
that are not some delimeter. startOfItem[maxSize] is guaranteed to
be at a valid address and to be a delimiter. The function is defined
elsewhere and works perfectly. */
unsigned int getSizeOfItem(char* startOfItem, unsigned int maxSize);
/* This function runs in a worker thread. It has an exception handler that is
omitted here for clarity, and because it is never run anyway. */
void itemizeAndAddToListbox (HWND hListbox, char* strings, unsigned int size) {
while (size) {
unsigned int sizeOfItem = getSizeOfItem(strings, size);
strings[sizeOfItem] = 0; //overwrite the delimiting character with null
SendMessage( hListbox, LB_ADDSTRING, (WPARAM) 0, (LPARAM) strings );
/* passing a pointer to a different thread is a no-no, but SendMessage
does not return until the message is processed, so no disposal issues
are possible. And I happen to know that all addresses from *strings
to strings[sizeOfItem] remain valid. */
strings += sizeOfItem+1;
size -= sizeOfItem+1;
};
}
Believe it or not, this works perfectly from a thread that did not create hListbox until the very last item, at which point the listbox causes an access violation by reading strings[size+1]. It throws the exception in the UI thread (the one that created the listbox), ignoring the worker thread's exception handler. SendMessage() inappropriately returns 0 instead of the listbox error code.
I made this work by sending user-defined messages from the worker thread to the UI thread's window, which in turn sends the LB_ADDSTRING message with the very same parameters to the very same listbox, and it works perfectly. The exception hasn't happened yet when the message is sent from the UI thread, but that's such a random difference that I'm nervous about the proper working code as well. Anybody know what the listbox is doing accessing memory beyond the null-terminated end of the string in the first place, and what I can do to prevent it from doing so?
Since the SendMessage() serializes the call onto the receiving thread, then I would expect the exception to happen on the UI thread because that's the one adding the string.
MSDN SendMessage:
'The return value specifies the result of the message processing; it depends on the message sent.' This is not the listbox error code from teh exception will not be put into the message field unless the message-hander puts it there.
What happens to 'size' at the end if you call in with one string of size 1? Will 'size' not be set to -1, ie. not false?
Rgds,
Martin
I'm building a client using dns-sd api from Bonjour. I notice that there is a flag called kDNSServiceFlagsShareConnection that it is used to share the connection of one DNSServiceRef.
Apple site says
For efficiency, clients that perform many concurrent operations may want to use a single Unix Domain Socket connection with the background daemon, instead of having a separate connection for each independent operation. To use this mode, clients first call DNSServiceCreateConnection(&MainRef) to initialize the main DNSServiceRef. For each subsequent operation that is to share that same connection, the client copies the MainRef, and then passes the address of that copy, setting the ShareConnection flag to tell the library that this DNSServiceRef is not a typical uninitialized DNSServiceRef; it's a copy of an existing DNSServiceRef whose connection information should be reused.
There is even an example that shows how to use the flag. The problem i'm having is when I run the program it stays like waiting for something whenever I call a function with the flag. Here is the code:
DNSServiceErrorType error;
DNSServiceRef MainRef, BrowseRef;
error = DNSServiceCreateConnection(&MainRef);
BrowseRef = MainRef;
//I'm omitting when I check for errors
error = DNSServiceBrowse(&MainRef, kDNSServiceFlagsShareConnection, 0, "_http._tcp", "local", browse_reply, NULL);
// After this call the program stays waiting for I don't know what
//I'm omitting when I check for errors
error = DNSServiceBrowse(&BrowseRef, kDNSServiceFlagsShareConnection, 0, "_http._tcp", "local", browse_reply, NULL);
//I'm omitting when i check for errors
DNSServiceRefDeallocate(BrowseRef); // Terminate the browse operation
DNSServiceRefDeallocate(MainRef); // Terminate the shared connection
Any ideas? thoughts? suggestion?
Since there are conflicting answers, I dug up the source - annotations by me.
// If sharing...
if (flags & kDNSServiceFlagsShareConnection)
{
// There must be something to share (can't use this on the first call)
if (!*ref)
{
return kDNSServiceErr_BadParam;
}
// Ref must look valid (specifically, ref->fd)
if (!DNSServiceRefValid(*ref) ||
// Most operations cannot be shared.
((*ref)->op != connection_request &&
(*ref)->op != connection_delegate_request) ||
// When sharing, pass the ref from the original call.
(*ref)->primary)
{
return kDNSServiceErr_BadReference;
}
The primary fiels is explained elsewhere:
// When using kDNSServiceFlagsShareConnection, there is one primary _DNSServiceOp_t, and zero or more subordinates
// For the primary, the 'next' field points to the first subordinate, and its 'next' field points to the next, and so on.
// For the primary, the 'primary' field is NULL; for subordinates the 'primary' field points back to the associated primary
The problem with the question is that DNSServiceBrowse maps to ref->op==browse_request which causes a kDNSServiceErr_BadReference.
It looks like kDNSServiceFlagsShareConnection is half-implemented, because I've also seen cases in which it works - this source was found by tracing back when it didn't work.
Service referenses for browsing and resolving may unfortunately not be shared. See the comments in the Bonjour documentation for the kDNSServiceFlagsShareConnection-flag. Since you only browse twice I would just let them have separate service-refs instead.
So both DNSServiceBrowse() and DNSServiceResolve() require an unallocated service-ref as first parameter.
I can't explain why your program chokes though. The first DNSServiceBrowse() call in your example should return immediately with an error code.
Although an old question, but it should help people looking around for answers now.
The answer by vidtige is incorrect, the may be shared for any operation, provided you pass the 'kDNSServiceFlagsShareConnection' flag along with the arguments. Sample below -
m_dnsrefsearch = m_dnsservice;
DNSServiceErrorType mdnserr = DNSServiceBrowse(&m_dnsrefsearch,kDNSServiceFlagsShareConnection,0,
"_workstation._tcp",NULL,
DNSServiceBrowseReplyCallback,NULL);
Reference - http://osxr.org/android/source/external/mdnsresponder/mDNSShared/dns_sd.h#0267