Xcode GCDAsyncSocket telnet connection - ios

I'm having trouble getting started with GCDAsyncSocket to use a telnet connection.
When I connect through terminal I get some text and it asks me to login.
With GCDAsyncSocket I can get a connection but can't get any text from it.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%s",__FUNCTION__);
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *err = nil;
if (![socket connectToHost:#"192.168.1.1" onPort:23 error:&err])
{
// If there was an error, it's likely something like "already connected" or "no delegate set"
NSLog(#"I goofed: %#", err);
}
[socket readDataWithTimeout:5 tag:1];
}
.
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
NSLog(#"Cool, I'm connected! That was easy.");
}
.
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(#"%s",__FUNCTION__);
NSString *responce = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responce=%#",responce);
}
data responds with fffd01ff fd1ffffb 01fffb03
response is always null.

Related

NSNetService doesn't contain any addresses

I'm hosting a service in a Mac application and connecting with an iOS app. While the iOS app will find the service, the service doesn't contain any addresses, so I can't connect a socket.
This is my hosting code on the Mac:
- (void)start {
queue = dispatch_queue_create("KeyboardServer", DISPATCH_QUEUE_CONCURRENT);
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:queue];
NSError *error = nil;
if ([socket acceptOnPort:0 error:&error]) {
service = [[NSNetService alloc] initWithDomain:#"local." type:#"_probonjore._tcp." name:#"TestServer" port:[socket localPort]];
service.delegate = self;
[service publish];
} else {
NSLog(#"Unable to create server");
}
}
This is the connecting code on iOS:
- (BOOL)connectToServer:(NSNetService *)service {
NSArray *addresses = service.addresses;
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:queue];
for (NSData *address in addresses) {
NSError *error;
if ([socket connectToAddress:address error:&error]) {
NSLog(#"Socket connected!");
return true;
}
}
return false;
}
The problem is, service.addresses is always empty and the loop instantly exits.
For anyone curious, I searched around and found a solution.
In the
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing
function, you need to:
Add the service to an array to stop the object being deallocated as soon as it goes out of scope
Set the delegate on the object so that you can respond to its address resolution
Call the function to make it resolve
Which looks like this:
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing {
NSLog(#"Found Service %#", [service name]);
[services addObject:service];
[service setDelegate:self];
[service resolveWithTimeout:5.0f];
}
You then want to implement
- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
and
- (void)netServiceDidResolveAddress:(NSNetService *)service
To catch when the address either resolves or doesn't resolve.

iOS cocoaAsyncSocket get data parse String return null

I try to connect telnet to my telnet server port 23 in iOS.
I use the "cocoaAsyncSocket" library.
I can received the data from the telnet.
But I try to decode to the string , the data is not my expect.
It will show
(null)
If I use NSASCIIStringEncodeing to decode.
It will show
ÿýÿý ÿý#ÿý'
I use the terminal command, telnet myIP 23.
I can get below in terminal.
james$ telnet 192.168.2.94 23
Trying 192.168.2.94...
Conn ected to txxxxx.xxxxx.com.
Escape character is '^]'.
Password:
how can I parse to the "Password:" string in iOS?
thank you .
my connect code below:
- (void)viewDidLoad {
[super viewDidLoad];
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
buffer = [[NSMutableData alloc] init];
[asyncSocket connectToHost:#"192.168.2.94" onPort:23 error:nil];
}
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
NSLog(#"did connect to host");
[asyncSocket readDataWithTimeout:-1 tag:0];
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(#"didReadData(%lu): %#", tag, #([data length]));
[buffer setLength:0];
NSString* message = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
// NSString* message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"message is: \n%#",message);
[asyncSocket readDataWithTimeout:-1 buffer:buffer bufferOffset:[buffer length] tag:tag];
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
NSLog(#"socket disconnect to host");
}

Disconnecting with server immediately after connecting

I have written a Singleton Class using GCDAsyncsocket Library to establish connection with any other device having same service using Bonjour.
On one device I am using its Method "startPublishing" to make it a Host(Server), from the Application on another Device(Client) I am calling "StartBrowsing" to find out the available Devices in Network. When user selects any of service in that Network I am calling method "initConnectionWithService", that initiate Connection flow by resolving address of NetService to connect.
BonjourUtilClass.h
#interface BonjourUtilClass : NSObject<GCDAsyncSocketDelegate,NSNetServiceDelegate,NSNetServiceBrowserDelegate>{
NSNetService *netServiceToPublish;
GCDAsyncSocket *socketPub;
NSNetServiceBrowser *netServiceToBrowse;
GCDAsyncSocket *socketSub;
NSMutableArray *mutArrServices;
GCDAsyncSocket *socketConnected;
}
+(id)sharedInstance;
-(void)startPublishing;
-(void)startBrowsing;
-(void)initConnectionWithService:(NSNetService*)netServiceToConnect;
-(void)disconnectWithCurrent;
#end
BonjourUtilClass.m
static BonjourUtilClass *sharedObject = nil;
#implementation BonjourUtilClass
+(id)sharedInstance{
if(!sharedObject){
sharedObject = [[BonjourUtilClass alloc]init];
}
return sharedObject;
}
#pragma mark - Browsing
-(void)startBrowsing{
if(mutArrServices){
[mutArrServices removeAllObjects];
}else{
mutArrServices = [NSMutableArray array];
}
netServiceToBrowse = [[NSNetServiceBrowser alloc]init];
netServiceToBrowse.delegate= self;
[netServiceToBrowse searchForServicesOfType:#"_mrug._tcp" inDomain:#"local."];
}
-(void)stopBrowsing{
}
-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing{
[mutArrServices addObject:aNetService];
if(!moreComing) {
// Sort Services
[mutArrServices sortUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES]]];
// Update Table View
[[NSNotificationCenter defaultCenter]postNotificationName:kNotifyReloadList object:mutArrServices];
}
}
-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)moreComing{
[mutArrServices removeObject:aNetService];
if(!moreComing) {
// Sort Services
[mutArrServices sortUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES]]];
// Update Table View
[[NSNotificationCenter defaultCenter]postNotificationName:kNotifyReloadList object:mutArrServices];
}
}
-(void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)aNetServiceBrowser{
NSLog(#"Search browser Did STOP search..");
[self stopBrowsing];
}
-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didNotSearch:(NSDictionary *)errorDict{
NSLog(#"Search browser Did not search..");
[self stopBrowsing];
}
#pragma mark - NetService Delegate
-(void)startPublishing{
socketPub = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *aError;
if([socketPub acceptOnPort:0 error:&aError]){
netServiceToPublish = [[NSNetService alloc]initWithDomain:#"local." type:#"_mrug._tcp" name:#"" port:socketPub.localPort];
netServiceToPublish.delegate =self;
[netServiceToPublish publish];
}else{
NSLog(#"Unable To Create Socket..");
}
}
//NetService Delegates
-(void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict{
NSLog(#"Failed To Publish : Domain=%# type=%# name=%# info=%#",sender.domain,sender.type,sender.name,errorDict);
}
-(void)netServiceDidPublish:(NSNetService *)sender{
NSLog(#"Service Published : Domain=%# type=%# name=%# port=%li",sender.domain,sender.type,sender.name,(long)sender.port);
}
//Resolving Address
- (void)netService:(NSNetService *)service didNotResolve:(NSDictionary *)errorDict {
[service setDelegate:nil];
}
- (void)netServiceDidResolveAddress:(NSNetService *)service {
// Connect With Service
if ([self connectWithService:service]){
NSLog(#"Did Connect with Service: domain(%#) type(%#) name(%#) port(%i)", [service domain], [service type], [service name], (int)[service port]);
} else {
NSLog(#"Unable to Connect with Service: domain(%#) type(%#) name(%#) port(%i)", [service domain], [service type], [service name], (int)[service port]);
}
}
#pragma mark - GCDSocket delegates
-(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
NSLog(#"Accepted new Socket: HOST : %# , CONNECTION PORT :%li",newSocket.connectedHost,(long)newSocket.connectedPort);
}
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
NSLog(#"Socket DisConnected %s,%#,%#",__PRETTY_FUNCTION__, sock,err);
if(socketPub == sock){
socketPub.delegate = nil;
socketPub = nil;
}else if (socketConnected == sock){
socketConnected.delegate=nil;
socketConnected = nil;
}
}
- (void)socket:(GCDAsyncSocket *)socket didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(#"Socket Did Connect to Host: %# Port: %hu", host, port);
// Start Reading
[socket readDataToLength:sizeof(uint64_t) withTimeout:-1.0 tag:0];
}
#pragma mark - Connection Methods
-(void)disconnectWithCurrent{
if(socketConnected){
[socketConnected disconnect];
socketConnected.delegate = nil;
socketConnected = nil;
}
}
-(void)initConnectionWithService:(NSNetService*)netServiceToConnect{
// Resolve Service
[netServiceToConnect setDelegate:self];
[netServiceToConnect resolveWithTimeout:30.0];
}
- (BOOL)connectWithService:(NSNetService *)service {
BOOL _isConnected = NO;
// Copy Service Addresses
NSArray *addresses = [[service addresses] mutableCopy];
if (!socketConnected || ![socketConnected isConnected]) {
// Initialize Socket
socketConnected = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
// Connect
while (!_isConnected && [addresses count]) {
NSData *address = [addresses objectAtIndex:0];
NSError *error = nil;
if ([socketConnected connectToAddress:address error:&error]) {
_isConnected = YES;
} else if (error) {
NSLog(#"Unable to connect to address. Error %# with user info %#.", error, [error userInfo]);
}
}
} else {
_isConnected = [socketConnected isConnected];
}
return _isConnected;
}
#end
But, On execution of above things very unexpected things happending, Device which is acting as Client is getting callback in didConnectedToHost and immediatly, another Callback is coming that is in didDisconnected
Logs on Client Device
2014-12-11 15:16:32.512 GCDSocketDemo[1419:71238] Did Connect with Service: domain(local.) type(_mrug._tcp.) name(ind506Bonjour) port(52026)
2014-12-11 15:16:32.659 GCDSocketDemo[1419:71238] Socket Did Connect to Host: 10.2.4.130 Port: 52026
2014-12-11 15:16:32.660 GCDSocketDemo[1419:71238] -[AppDelegate socketDidDisconnect:withError:],<GCDAsyncSocket: 0x7fa0a3533b90>,Error Domain=GCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo=0x7fa0a3532f70 {NSLocalizedDescription=Socket closed by remote peer}
Logs On Server Device
2014-12-11 15:15:48.546 GCDSockrtMacDemo[1397:70851] Service Published : Domain=local. type=_mrug._tcp. name=ind506Bonjour port=52026
2014-12-11 15:16:32.585 GCDSockrtMacDemo[1397:70851] Accepted new Socket: HOST : 10.2.4.130 , CONNECTION PORT :52029
2014-12-11 15:16:32.613 GCDSockrtMacDemo[1397:70851] -[BonjourUtilClass socketDidDisconnect:withError:],(null),(null)
Comment of Paulw11 Helped me to find out the Solution. Actually I stored Socket on client side, but forgot to Store reference of new Socket getting in callback method "didAcceptNewSocket".
So the Method didAcceptNewSocket should be as below:
-(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
NSLog(#"Accepted new Socket: HOST : %# , CONNECTION PORT :%li",newSocket.connectedHost,(long)newSocket.connectedPort);
socketConnected = newSocket;
}
So that newSocket received in this method can be persist for further communication. In earlier case it was releasing at end of method.

iOS devices not receiving UDP multicast using GDAsyncUdpSocket

The code below is intended to receive UDP multicast messages on 239.255.255.250 and simply NSLog the contents of the message.
If I address a message to the IP of the iOS device (i.e. from a terminal echo foo | nc -u 10.1.10.249 1900) the message is received and NSLog'd.
However, if I broadcast a message to the multicast address (echo bar | nc -u 239.255.255.250 1900), the message is not received.
No error messages are logged at start up.
Thoughts on where I'm going awry?
#import "ViewController.h"
#import "GCDAsyncUdpSocket.h"
#interface ViewController () {
GCDAsyncUdpSocket *udpSocket;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
if (![udpSocket bindToPort:1900 error:&error]) {
NSLog(#"Error starting server (bind): %#", error.description );
return;
}
if(![udpSocket joinMulticastGroup:#"239.255.255.250" error:&error] ) { //]onInterface:#"en0" error:&error]) {
NSLog(#"Error joining multicast group: %#",error.description);
return;
}
if (![udpSocket beginReceiving:&error]) {
[udpSocket close];
NSLog(#"Error starting server (recv): %#", error.description);
return;
}
NSLog(#"Udp server started on port %#:%hu", [udpSocket localHost_IPv4], [udpSocket localPort]);
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"message rec'd: %#:%hu %#\n", [udpSocket localHost_IPv4], [udpSocket localPort],msg);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
You're missing a key function that stumped me for a time, too.
[udpSocket enableBroadcast:YES error:&error];
This will allow you to send broadcast packets and receive broadcasted packets from your multicast group.

GCDAsyncSockets, get answer

I'm trying to test a server connection with the GCDAsyncSocket.
https://github.com/robbiehanson/CocoaAsyncSocket
I want to connect to a ip + port and get a message, whether it worked, or not.
I'm so far right now.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
NSString *host = #"www.google.de";
uint16_t port = 21;
NSError *error = nil;
if(![asyncSocket connectToHost:host onPort:port error:&error])
{
NSLog(#"ERROR %#!!!", error);
}
else{
NSLog(#"NO ERROR %#!!!", error);
}
[asyncSocket writeData:#"DATA" withTimeout:3 tag:0];
return YES;
}
But how can i check whether the Data was written or not?
if(![asyncSocket connectToHost:host onPort:port error:&error])
always get me a no error.
You have to implement the socket:didWriteDataWithTag: delegate method.
From "GCDAsyncSocket.h":
/**
* Called when a socket has completed writing the requested data. Not called if there is an error.
**/
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag;
If the write times out then the connection is closed and the delegate method
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;
is called.

Resources