I tried to connect to the server and send some information to the server(like username, password..), and the server send me back the ID (string type). The problem is I can not get the ID. Could anyone help me? I am beginner in IOS coding. Thanks.
Here is the codes:
After I click the button, it will call my own function to get serverIP which is a string and Port which is a int.
Then that function will call this function to connect the server:
(void)logInCheck {
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
uint16_t port = serverPort;
if (![asyncSocket connectToHost:serverIP onPort:port error:&error])
{
DDLogError(#"Unable to connect to due to invalid configuration: %#", error);
}
else
{
DDLogVerbose(#"Connecting...");
[self passDataToServer];
}
}
//DataPassToServer is a NSString that hold my data
(void)passDataToServer
{
NSData *requestData = [DataPassToServer dataUsingEncoding:NSUTF8StringEncoding];
[asyncSocket writeData:requestData withTimeout:-1.0 tag:0];
[asyncSocket readDataWithTimeout:-1 tag:0];
}
//this function call successfully
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
DDLogVerbose(#"socket:didConnectToHost:%# port:%hu", host, port);
}
//this function call successfully
(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
DDLogVerbose(#"socket:didWriteDataWithTag:");
}
//This function does not run !!! Nothing print out.
(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
DDLogVerbose(#"socket:didReadData:withTag:");
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"ID = %#",response);
[asyncSocket readDataWithTimeout:-1 tag:0];
}
I don't know about your server implementation but, most implementations would read up to the first newline character before processing the request.
So make sure that your [DataPassToServer dataUsingEncoding:NSUTF8StringEncoding] includes a newline character ("\n") at the end.
Your code looks fine and works for me.
Related
I'm trying to send a message to a server and receive a response using my iPhone. I can connect to the server using:
telnet 123.123.123.1 6000
Trying 123.123.123.1...
Connected to 123.123.123.1.
Escape character is '^]'.
?VERSION
OK
VERSION=PROTOCOL: 1.1.0
?VERSION is my question
OK states it received and understood the question
VERSION= is the response from the server
so I'm trying to do the same thing but with xcode
So I have this in my viewDidLoad
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:mainQueue];
asyncSocket.delegate = self;
NSString *host = #"123.123.123.1";
uint16_t port = 6000;
NSLog(#"Connecting to \"%#\" on port %hu...", host, port);
NSError *error = nil;
if (![asyncSocket connectToHost:host onPort:port withTimeout:5.0 error:&error])
{
NSLog(#"Error connecting: %#", error);
}
else
{
NSLog(#"Connecting...");
}
And I have the following code showing it connected
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:
(UInt16)port
{
NSLog(#"socket:%p didConnectToHost:%# port:%hu", sock, host, port);
// We're just going to send a test string to the server.
NSString *myStr = #"?VERSION";
NSData *myData2 = [myStr dataUsingEncoding:NSUTF8StringEncoding];
[asyncSocket writeData:myData2 withTimeout:-1 tag:0];
}
And the following to show it wrote
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
NSLog(#"WRITING");
[asyncSocket readDataToData:[GCDAsyncSocket LFData] withTimeout:-1 tag:0];
}
Sadly this never gets called
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSString *tempString = [[NSString alloc]initWithData:data
encoding: NSUTF8StringEncoding];
}
I'm lost and really need some assistance
It is because you say write AND read at the same time. First call [asyncSocket writeData:myData2 withTimeout:-1 tag:0]; and in didWriteDataWithTag call [asyncSocket readDataToData:[GCDAsyncSocket LFData] withTimeout:-1 tag:0];. You are on one thread - dispatch_get_main_queue() - it can't do two things at one time.
In my app I'm using GCDAsyncSocket and I write and read in this way:
NSData *bufferWriteData = [NSData dataWithBytesNoCopy:bufferWrite length:17 freeWhenDone:YES];
[self.socket writeData:bufferWriteData withTimeout:-1 tag:1];
[self.socket readDataWithTimeout:-1 tag:1];
after I read in the delegate method the data:
- (void) socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
NSLog(#"did read data");
if (tag == 1){
//analyze my data...
[self.socket readDataWithTimeout:-1 tag:1];
}
inside this delegate method I recall the "readDataWithTimeout" so in this way I read all data.
The problem id when I do a new call, if I do:
[self.socket writeData:bufferWriteData withTimeout:-1 tag:2];
[self.socket readDataWithTimeout:-1 tag:2];
I start a new write and a new read with tag = 2;
When the delegate method "didReadData" is called my code enter inside the block of tag = 1; it seems that it don't recognize the new tag.
Why it happen?
There are several ways to handle this. In your case, the best way probably just used a terminator to indicate the end of that data segment. You can read up there: TCP is a stream.
NSData *MyCommandTerminator(void)
{
return [NSData dataWithBytes:"\x0D\x0A\x0B\x0A" length:4];
}
//callback from Asyncsocket for incoming data
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag //sender and receiver
{
NSLog(#"GCDAsyncSocket didreaddata");
// do what you wish with data and read again using a terminator
[sock readDataToData:MyCommandTerminator() withTimeout:-1 tag:1]; //tag is not being used here
}
// your method to send data
-(void)sendData:(NSData *)data
{
// NSData *bufferWriteData = [NSData dataWithBytesNoCopy:bufferWrite length:17 freeWhenDone:YES];
NSLog(#"Sendata wehere _peerSocket is your instance of GCDAsyncSocket");
NSMutableData *myData = [[NSMutableData alloc] initWithData:data];
[myData appendData:MyCommandTerminator()];
[_peerSocket writeData:myData withTimeout:-1 tag:2]; // tag is not being used here
}
I am new to objective C, as a whole and iOS in particular, but i spent the last day to learn it.
i've been trying to create a simple app that reads data from a socket.
I understood that Asyncsocket is the best solution and have started working with it, but I encountered a problem.. it goes through all the delegates (connected to host, read data, disconnected) but then it drifts off and gets stuck somewhere.
heres the code:
- (void) connect:(NSString *)ip PORT:(NSInteger)port
{
//open asyncsoket
connectSocket = [[AsyncSocket alloc] initWithDelegate:self];
[connectSocket setDelegate:self];
// open connection
NSError *error = nil;
if (![connectSocket connectToHost:ip onPort:port error:&error]) {
NSLog(#"Error starting client: %#", error);
return;
}
}
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
// if connection was succeful read from socket
NSLog(#"connected to server");
[sock readDataWithTimeout:-1.0 tag:0];
}
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
//if did read data
[connectSocket readDataWithTimeout:-1 tag:0];
to_pass = data;
[sock disconnect];
}
- (void)onSocketDidDisconnect:(AsyncSocket *)sock{
// nothing to do
}
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err{
//nothing to do
}
if i follow by break points it seems i goes through all those it needs, but then goes to assembly code and stops here:
libsystem_kernel.dylib`mach_msg_trap:
0x2178f70: movl $4294967265, %eax
0x2178f75: calll 0x217f4bc ; _sysenter_trap
0x2178f7a: ret ----> right here
0x2178f7b: nop
Im would to send a UDP broadcast from an iPhone, and then listen for a UDP response with a timeout period from all devices with such port opened. Does my custom device from the same subnet would answer? ( if mine is 192.168.1.100 and IP of custom device is 192.168.1.201 )
What to use "SmallSockets" or "cocoaAsyncSocket" ?
What function to use to listen for response?
Thanx!
i decided to use cocoaAsyncSocket.
To broadcast you can use:
[udpSocket sendData:datatosend toHost:#"192.168.1.113" port:port withTimeout:-1 tag:0];
to receive:
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext
{
NSString *msg = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSString *host = nil;
uint16_t port = 0;
[GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];
if (msg)
{
NSLog(#"Message = %#, Adress = %# %i",msg,host,port);
}
else
{
NSLog(#"Error converting received data into UTF-8 String");
}
}
I really need some help with my project...
I need to exchange data with my server written in Java. I tried using GCDAsyncSocket, and I can send message to server, read it on server, but when server sends response to client, I can't (don't know how to) read it on client. Here is part of my code:
- (void) someMethod{
NSError *err = nil;
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
if(![asyncSocket connectToHost:#"localhost" onPort:7777 error:&err]){
// If there was an error, it's likely something like "already connected" or "no delegate set"
NSLog(#"I goofed: %#", err);
}
NSString *requestStr = #"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><root><service>1</service><type>1</type><userProperties><username>ivo</username></userProperties></root>";
NSData *requestData = [requestStr dataUsingEncoding:NSUTF8StringEncoding];
[asyncSocket writeData:requestData withTimeout:-1.0 tag:0];
[asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:1.0 tag:0];
[asyncSocket disconnectAfterWriting];
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
if (tag == 0)
NSLog(#"First request sent");
else if (tag == 2)
NSLog(#"Second request sent");
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#",str);
}
Please help, if there is another way I am willing to try as I am getting desperate...
I see that you're sending XML, with no particular terminator at the end of your request data, yet you're expecting the server to send a response terminated by a \r\n?
What does the protocol specify?
Sending and receiving data over tcp is a common cause of confusion because tcp is stream based. It has no concept of individual reads/writes. It treats all data as conceptually a never ending stream. The protocol dictates message boundaries. For a better explanation, see the "Common Pitfalls" article from GCDAsyncSocket's wiki:
https://github.com/robbiehanson/CocoaAsyncSocket/wiki/CommonPitfalls
I think it will help explain a lot.