Receiving Error Domain=kCFErrorDomainCFNetwork Code=2 when attempting to read from ReadStream - iphone

I'm attempting to synchronously read from a CFReadStream objected created by CFStreamCreatePairWithSocketToHost. The stream opened fine but when I attempt to invoke CFReadStreamRead on it in a loop, CFReadStreamRead() returns -1 and the resulting error is:
Error Domain=kCFErrorDomainCFNetwork Code=2 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 2.)" UserInfo=0x14a920 {kCFGetAddrInfoFailureKey=8}
I'm also receiving this same exact error when using this ReadStream asynchronously- the first callback I receive is this error.

The short story: Probably a DNS resolution failure.
The docs say "The streams do not open a connection to the specified host until one of the streams is opened", and for kCFGetAddrInfoFailureKey,
Querying this key returns the last error code returned by getaddrinfo(3) in response to a DNS lookup. To interpret the results, look up the error code in /usr/include/netdb.h.
netdb.h says
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */

I was able to fix this by putting in Google's DNS servers (8.8.8.8,8.8.4.4) in the wifi connection in the Settings app. The issue was that our devices were on a network that first required you to agree to some terms of service on a proxy login web page, much like hotels and coffee shops do. Safari worked fine after agreeing, but the app didn't, even after agreeing in Safari. Switching to alternate DNS worked (so did putting in the IP address instead of the DNS entry of our server, but I didn't want to hard-code an IP address).

I was able to eliminate this error by removing https:// from the host String.
NSStream.getStreamsToHostWithName("https://example.com" ...
You may need to set the appropriate security level:
inputStream!.setProperty(NSStreamSocketSecurityLevelTLSv1, forKey: NSStreamSocketSecurityLevelKey)
outputStream!.setProperty(NSStreamSocketSecurityLevelTLSv1, forKey: NSStreamSocketSecurityLevelKey)

Related

Bidirectional communication of Unix sockets

I'm trying to create a server that sets up a Unix socket and listens for clients which send/receive data. I've made a small repository to recreate the problem.
The server runs and it can receive data from the clients that connect, but I can't get the server response to be read from the client without an error on the server.
I have commented out the offending code on the client and server. Uncomment both to recreate the problem.
When the code to respond to the client is uncommented, I get this error on the server:
thread '' panicked at 'called Result::unwrap() on an Err value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', src/main.rs:77:42
MRE Link
Your code calls set_read_timeout to set the timeout on the socket. Its documentation states that on Unix it results in a WouldBlock error in case of timeout, which is precisely what happens to you.
As to why your client times out, the likely reason is that the server calls stream.read_to_string(&mut response), which reads the stream until end-of-file. On the other hand, your client calls write_all() followed by flush(), and (after uncommenting the offending code) attempts to read the response. But the attempt to read the response means that the stream is not closed, so the server will wait for EOF, and you have a deadlock on your hands. Note that none of this is specific to Rust; you would have the exact same issue in C++ or Python.
To fix the issue, you need to use a protocol in your communication. A very simple protocol could consist of first sending the message size (in a fixed format, perhaps 4 bytes in length) and only then the actual message. The code that reads from the stream would do the same: first read the message size and then the message itself. Even better than inventing your own protocol would be to use an existing one, e.g. to exchange messages using serde.

Route SockJS connection at variable URL?

Let's say I have a bunch of clients who all have their own numeric IDs. Each of them connect to my server through SockJS, with something like:
var sock = new SockJS("localhost:8080/sock/100");
In this case, 100 is that client's numeric ID, but it could be any number with any number of digits. How can I set up a SockJS router in my server-side code that allows for the client to set up a SockJS connection through a URL that varies based on what the user's ID is? Here's a simplified version of what I have on the server-side right now:
public void start() {
HttpServer server = vertx.createHttpServer();
SockJSHandler sockHandler = SockJSHandler.create(vertx);
router.route("/sock/*").handler(sockHandler);
server.requestHandler(router::accept).listen(8080);
}
This works fine if the client connects through localhost:8080/sock, but it doesn't seem to work if I add "/100" to the end of the URL. Instead of getting the default "Welcome to SockJS!" message, I just get "Not Found." I tried setting a path regex and I got an error saying that sub-routers can't use pattern URLs. So is there some way to allow for the client to connect through a variable URL, whether it's /sock/100, /sock/15, or /sock/1123123?
Ideally, I'd be able to capture the numeric ID that the client uses (like with routing REST API calls, when you could add "/:ID" to the routing path and then capture the value that the client uses), but I can't find anything that works for SockJS connections.
Since it seems that SockJS connections are considered to be the same as sub-routers, and sub-routers can't have pattern URLs, is there some work-around for this? Or is it not possible?
Edit
Just to add to what I said above, I've tried a couple different things which haven't seemed to work yet.
I tried setting up an initial, generic main router, which then re-directs to the SockJS handler. Here's the idea I had:
router.routeWithRegex("/sock/\\d+").handler(context -> {
context.reroute("/final");
});
router.route("/final").handler(SockJSHandler.create(vertx));
With this, if I access localhost:8080/sock/100 directly through the browser, it takes me to the "Welcome to SockJS!" page, and the Chrome network tab shows that a websocket connection has been created when I test it through my client.
However, I still get an error because the websocket shows a 200 status code rather than 101, and I'm not 100% sure as to why that is happening, but I would guess that it has to do with the response that the initial handler produces. If I try to set the initial handler's status code to 101, I still get an error, because then the initial handler fails.
If there's some way to work around these status codes (it seems like the websocket is expecting 101 but the initial handler is expecting 200, and I think I can only pick one), then that could potentially solve this. Any ideas?

AT+CMGS returns ERROR 302

I'm trying to send a SMS using AT commands and after typing the cellphone number it show the CMS: ERROR 302.
What I'm doing:
AT
OK
AT+CMGF=1
OK
AT+CMGS="<3 digit local area code><7 digit cellphone number>"<Enter>
+CMS: ERROR 302
I've found this post: AT+CMGS returns ERROR but couldn't find a solution. Am I typing something wrong? I've changed SMS-encoding to GMS as the post describes.
Try this:
AT
AT+CMGF=1
AT+CSCA="sms tel. service",145
AT+CMGS="tel. number"
text message here
^Z
Some modems need set CSCA (SMS Service Center Address) always.
And look here for a examples and descriptions.
I found out that sending exactly the same AT commands by hand worked, but sending them from a controller did not (with waiting for the correct answers). Getting the 302 error. But then doing all commands a lot slower with waits of 2 secs in between it suddenly started to work. Apparantly the SIM900 needs more time after it answers, or something.

Error when trying to promote SSOTicket

I am trying to issue a SSO ticket for a FTP send port. I have created affiliate application with a mapping that is working for a receive port.
For the send port I am using a pipeline component in encode stage with just standard code:
ISSOTicket ssoTicket = new ISSOTicket();
inmsg.Context.Promote("SSOTicket",
"http://schemas.microsoft.com/BizTalk/2003/system-properties", ssoTicket.IssueTicket(0));
return inmsg;
When I try to promote the result from IssueTicket(0) I get an error message saying that
The property "SSOTicket" has a value with length greater than 256 characters.
How is that even possible?
I solved it. The problem was that I tried to promote the SSOTicket property when I should have used inmsg.Context.Write.

stringWithContentOfURL return an empty string

i have a problem with the method "[NSStrng stringWithContentOfURL:url]";
all things worked so fine until i change my url from a web address to an ip address with which i got an empty string.
Did you have a solution or an idea?
Thks
Use a method that returns an error status (e.g. +stringWithContentsOfURL:encoding:error:) and check the error return.
update: NSCocoaErrorDomain Code=256 is "NSFileReadUnknownError", which means "file read error, reason unknown" (not very helpful). Probably there's something wrong with the URL (misspelled pathname, wrong IP address, etc.)
Numeric IP addresses most definitely are supported in URLs, so that's not the problem.
see also iPhone - dataWithContentsOfURL: does not work for some URLs