GCDAsyncSocket readDataWithTimeout is not continuing to read data - ios

I am using GCDasyncsocket in my iOS app to send a string over a socket connection and then to read a string every second over the same socket connection. I am also creating a second socket to the same server on a different port ad reading once a second there as well.
My write is working properly and the first few reads on each socket work properly, but then the connection appears to stop.
My current method of reading every second is to kick off the reads by calling
[asyncSocket readDataWithTimeout:1 tag:1];
[asyncSocket_Emove readDataWithTimeout:1 tag:2];
at the end of "didConnectToHost" and the similarly calling them again at the end of "didReadDatawithTag"
I can provide more details if needed, but does anyone have an idea why the socket is stopping?

Replace this line
[asyncSocket readDataWithTimeout:1 tag:1];
with this
[asyncSocket readDataWithTimeout:-1 tag:1];
may work for you.

Related

SRWebsocket close the connection ios

I am using SRWebsocket in my connection class I am trying to disconnect the socket when the app goes to background i have tried these things
SRWebSocket *_webSocket;
-(void)close
{
[_webSocket close];
_webSocket.delegate = nil;
_webSocket = nil;
}
but it is not closing the socket please help me in doing so .
Keep in mind that, if you nil the websocket delegate at this point, when the socket actually closes (it's not inmediate), there will be no delegate to process the webSocket:diCloseWithCode: event. But the socket should certainly be closed anyway.
It may not be that, but it would make more sense to just send the close message. Then wait for the didClose and there, you can nil both the delegate and the actual _websocket.

How does didAcceptConnectionWithInputStream:outputStream: get called?

My first question is how do I get the didAcceptConnectionWithInputStream:outputStream: callback in NSNetServiceDelegate to get called?
Follow up question: can I still establish a connection between a client and server, although I never get a callback saying that a connection was accepted (via didAcceptConnectionWithInputStream:outputStream:)?
I understand that calling publishWithOptions, while passing in the NSNetServiceListenForConnections option is supposed to result in the NetServiceDelegate callback (didAcceptConnectionWithInputStream:outputStream:) to be called. However, that callback is not getting called.
Here are the steps I am taking, to publish:
Create NSNetService with
self.netService = [[NSNetService alloc] initWithDomain:#""
type:_serviceType
name:(_name == nil) ? #"" : _name
port:0];
Schedule service in current runloop, in default mode
Set the delegate to my Server wrapper object
call publishWithOptions:NSNetServiceListenForConnections
Here are the steps I take, to browse services:
Create an NSNetServiceBrowser, and set its delegate to my client wrapper object
Call searchForServicesOfType for the same service type and domain as NSNetService
List services in a UITableView for the UI, to allow a user to select a service
When a user selects a service, set the service's delegate to my client object, and call getInputStream:outputSteam: on the service
After getInputStream:outputSteam: returns success, I would expect didAcceptConnectionWithInputStream:outputStream: to get called. However this does not occur.
Thanks for your help!
The problem is that didAcceptConnectionWithInputStream:outputStream: must be called from the side accepting the connection.
Once the service is available, you call get the streams
[service getInputStream:&istream outputStream:&ostream]
Once this happens on the side receiving the request the delegate method
- (void)netService:(NSNetService *)sender didAcceptConnectionWithInputStream:(NSInputStream *)inputStream outputStream:(NSOutputStream *)outputStream
will be called
In my experience, it is not the act of calling getInputStream:outputStream: on the client that causes didAcceptConnectionWithInputStream:outputStream: to be called on the server.
On the client, after calling getInputStream:outputStream:, your client then needs to call [inputStream open] and [outputStream open] before the didAcceptConnectionWithInputStream:outputStream: will be called.
It's all a part of lazy initialization.
Calling getInputStream:outputStream: will give you back two perfectly good NSStreams ready to use. So, say, you want to write some data? First, open the write stream...
BAM! netService:didAcceptConnectionWithInputStream:outputStream: is called.

Asynchronous Values Update using GCDAsynSocket api

I am developing one application in which I need to update multiple values like Engine RPM,Speed etc. parameters at a time using OBD connector. I need to achieve asynchronous command/response . For this I am sending commands using [gcdAsyncSocket writeData:data withTimeout:-1 tag:uniqueTag]; asynchronously with unique tag.
But when gcdAsync's delegate method "socketDidReadDatawithTag" is called, it returns the data but it is not proper.e.g. If I have sent one command "010C\r" (Read RPM), and "010D\r" (Speed),with Tag 263 and 264 respectively ,and if I parse the response with tag 264 in socketDidReadDatawithTag , sometimes it returns me the data of RPM. (My response gets Mixed up or OBD Device is unable to handle asynchronous response)
NSLog(#"Command Sent for Async : %#",commandString);
NSData *data = [commandString dataUsingEncoding:NSASCIIStringEncoding];
long obdObjectTag = [obdObject getPIDTag];//Unique Tag
[gcdAsyncSocket writeData:data withTimeout:-1 tag:obdObjectTag];
NSData *readData = [#">" dataUsingEncoding:NSASCIIStringEncoding];
[gcdAsyncSocket readDataToData:readData withTimeout:-1 tag:obdObjectTag];
And in socketdidReadDatawithTag data and tag are mismatched.
The OBD-II connector (I assume it's an ELM-327) cannot really handle asynchronous calls as far as I know.
It cannot handle multiple requests at once. You send 1 command, and the OBD-II device will gather that info from the OBD-bus and return with an answer. Then it will process your next command. Ofcourse, the commands you send end up in a buffer, that will be processed one by one.
I'm thinking this might be a problem for you to make it, but I'm not sure.
I'm not familiar at all with the ios programming and what happens with those tags. You set those tags to identify what paramters are the data for?
In the reply data, you can also see for what parameter it is meant, so in the answer itself you can see that data represents RPM or Speed etc.
I hope the OBD-II part has shed some light on it. Will check this question more for some discussion perhaps.

Obj-C: How to make UDP packet's Source Port consistent in GCDAsyncUdpSocket? source port alway change

I have using following code to crate UDP packets.I using bindToPort to setup Source Port.
[asyncUdpSocket bindToPort:7701
error:&socketError])
However, ! found only first time I go through those codes can get a right source port. Rest times, they are all wrong!! My bind to port should be 7701.
GCDAsyncUdpSocket *asyncUdpSocket;
asyncUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
delegateQueue:dispatch_get_main_queue()];
[asyncUdpSocket setPreferIPv4];
if ([asyncUdpSocket bindToPort:7701
error:&socketError]){
NSLog(#"Bind to Port fail");
}
[asyncUdpSocket enableBroadcast:NO error:&socketError];
[asyncUdpSocket sendData:data
toHost:#"192.168.16.77"
port:7701
withTimeout:-1
tag:0];
Question:
How to make UDP packet's Source Port consistent in GCDAsyncUdpSocket?
The reason of variable port number is I am using ARC. The instance might not be released at next time alloc and init.
Everytime I call this part code I create a new GCDAsyncUdpSocket object, then try to bind the port and then send the message. These objects are being dealloced only at a later time when I use ARC. So, actually I am trying to bind to the port several times which is not possible. Once the port is bound, I cannot bind it any more.

GCDAsyncSocket for iOS is not writing out the buffer

Basically I write an NSData object:
[asyncSocket writeData:JSONRequestData withTimeout:-1 tag:1];
Which when run, invokes the delegate
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
But for some reason, when the write goes to the buffer... it's not written out to the server.
When I stop my build, I guess the socket decides to write everything and the server ends up seeing it.
How would I fix this? There's no way to flush a CocoaAsyncSocket since it's not necessary...
I've tried adding line endings, like "/n" and all, but that doesn't do anything either.
This is based on user523234's suggestion.
Basically the NSData that you're writing out needs to have some kind of signal to tell the socket that no more data will be coming in.
I appended
[GCDAsyncSocket CRLFData];
to the NSData object
Note: to use the
appendData:
Method, you must convert NSData to NSMutableData.

Resources