How to use sockets in iOS? - iphone

I have to implement an iOS application, which connects to a web server and receives events from it, i.e. server long polling. I plan to use the AsyncSocket library.
My idea is to open a socket on the iPhone, send it to the server the first time I connect to it, and then listen infinitely to the socket and update the GUI accordingly to the events the server sends to it. Here are my questions:
Is this a correct approach and if not - how it should be done?
Can the server send data to the socket I give to it (as long as the socket is opened), if the iPhone and the server are on different networks, and the iPhone is on a local network?

Yes. 2. Yes.
On the fone, you will get information arriving in to the fone probably something like this:
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData*)data withTag:(long)tag
{
[data getBytes:&getMe length:sizeof(CommProt)];
// do not forget to roll in the next read...
[sock readDataToLength:sizeof(CommProt) withTimeout:-1 tag:0];
// now parse that command
}
and on the fone you will send information from the fone quite likely something like this (there are a couple of different approaches)...
-(void) mySendStringData:(NSString *)sss
{
// so easy, thank goodness for AysncSocket
NSData* data = [sss dataUsingEncoding: NSASCIIStringEncoding];
[theSocket writeData:data withTimeout:0.5 tag:0];
[theSocket writeData:quickCR withTimeout:0.5 tag:0];
// (in the protocol at hand, we are using a delimiter on the end (a CR))
}
Note. It is possible this post i made could be helpful to you: it gives the lowdown on protocols in iOS:
Tablet(iPad/Android)-Server Communication Protocol
I hope it helps.
Conceivably this could help iPad and Arduino Integration and this secret knowledge could help Client/Server GKSessions Cheers

Related

How to transfer an image using UDP protocol in iPhone?

I have tried using GCDAsyncUdpPacket.m and .h files for creating a udp communication channel. But through that i could send only one line messages. I need to send an entire file for example an Image.
Any help would be much appreciated as I am totally new to this platform.
Since UDP is not an error checked protocol, just cramming the binary data down a UDP socket will not be reliable, as some of the packets will likely be dropped, or arrive out of order at the far end.
If you want to ensure error-checked, in-order, and reliable data, open a TCP socket and send it that way.
In IOS, you can use the NSStream class to do this, though you'll have to look at a lot of sample code to understand the various ways it can be used in an iPhone app. To implement it well, you need to understand how run-loops work (NSRunLoop) and how delegation works in Cocoa.
For me, I tend to avoid all this and start network tasks on a separate NSThread, opening a TCP socket using unix's socket(), connect() and send() primitives. Once you get these working, they can be cut and pasted into other code (or put into a personal code library) so you don't have to remember how to do it. :-)
There is a lot of sample code out there for the BSD primitives socket(), accept(), bind(), connect(), send(), and recv().

iPhone communication using Sockets [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm trying to to use an application to communicate with Windows via sockets. At the minimum, I'm trying to at least figure out how I can create a connection from the iPhone (maybe using the iPhone to ping the Windows machine?) I'm not really clear on where I need to start. I'm pretty new to iOS development in general, and brand new to socket/network programming. I've tried several tutorials that haven't gotten me far. My goal is:
Connect to a server via sockets (the server will be a Windows machine with a service waiting for incoming connections from the iPhone)
I will eventually be sending JSON packets to the server, as well as receiving JSON packets from the server
Come up with a response in the iPhone indicating success or failure
If possible, I would like to write/build the client piece first, but I have been lost thus far. Hopefully the nice folks in the SO community can lend a hand and point me in the right direction.
Thanks in advance!
Your question is very wide especially that it does not target a specific programing problem. I will give you some guidelines or point of start.
For iPhone you need to learn how to work with NSStream and you might start from here: Stream Programming Guide for Cocoa. You will need an output stream and an input stream so you can manage outgoing and incoming communications easily and in parallel. In other words you will benefit from the NSInputStream and the NSOutputStream classes which are derived from the main NSStream class. When you will send data using streams you will send raw data using uint8_t buffers so it is not obligatory to use JSON packets; I personally don't, but it is up to you.
On Windows I assume you will be using C# so you will need to learn TcpListener which listens on a certain IP address and a port number that you specify. This can start you up a bit: TcpListener Class. Also you will need TcpClient through which you will read and write to the stream.
For efficient server you need to work Asynchronously and TcpClient has synchronous and asynchronous methods for that. Also for better functionality you might need to use threading in your server, or use the built in BackgroundWorker class which makes things much more easy.
I don't suggest programming the client alone then the server, I believe that they should go in parallel because it is a 2 sided communication and if you try that you will see that you must work little here and little there. It is not a surprise if I tell you that when I work on my client/server app I have on my desk a Mac and a PC and I switch between them every while.
Finally, I would like to comment on something which you did not ask about. Since your client is a mobile device then you have to expect that it is not always on (or no Internet connection always on it), therefore prepare yourself to have some database work in the server to be able to store messages that need to be sent later...
I hope this can help you start up. If you have a more specific question I might be able to illustrate better. By the way, this job is not that easy but it is great fun if you really like programming, especially when you start to get your first results ;)
If you really must use sockets, do yourself a favour and grab a nice socket library like AsyncSocket. https://github.com/robbiehanson/CocoaAsyncSocket
But better still try doing it over http first and only move to sockets when you really must do so.
If the server is using some kind of custom protocol, you can use BSD socket API. If the server is speaking HTTP protocol, then use either:
NSURLConnection - for asynchronous communication from the main thread.
Load synchronously using NSData but from a separate thread.
Example for #2:
NSString *url = #"http://example.com";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString: url]];
NSString *str = [[NSString alloc]
initWithBytes: [data bytes]
length:[data length]
encoding: NSUTF8StringEncoding];
If you use HTTP, as already stated, life will be much easier. No use in reinventing the wheel when you already have a protocol as extensive and as widely used as HTTP.
AFNetworking is a nice library for communicating to a web server and comes built-in with the ability to encode/decode JSON.
Example using AFNetworking to communicate using HTTP, JSON, and REST API.
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:#"POST"
path:#"user/login"
parameters:[[NSDictionary alloc] initWithObjectsAndKeys:user, #"username", password, #"password", nil]];
//Make operation from request
AFJSONRequestOperation *jsonOperation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
//Block will be called when request is successful
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
//Block will be called if request has failed
}];
//Start request
[httpClient enqueueHTTPRequestOperation:jsonOperation];
Pretty easy to use, I think it is easier than NSURLConnection. The use of blocks makes it a lot more initiative. Plus, you will not have to worry about JSON encoding/decoding. The JSON will be encoded/decoded for you directly from an objective-c object to JSON (or from JSON to objective-c object).

AsyncSocket writeData Terminator

I am porting a Java middleware client to objC. The java client uses the java stream.write and stream.flush at the end of the send. For the java client to send to the Echo server I need to add the stream.writeBytes("\r\n"); followed by stream.flush for the server to bounce the message back.
I am using the asyncsocket to send messages to the middleware's server, but after successfully opening the socket, the middleware does not react to a message sent using
[socket writeData:sendData withTimeout:-1 tag:0];
Also the middleware does not react to the message in the buffer when the socket is closed.
I am currently using
[socket writeData:[AsyncSocket CRLFData] withTimeout:-1 tag:0];
to flush the socket
I know this will not be the last time an assumption will come back to byte me.
I assumed that the java.io write was the same as BSD send or sendto, but from other posts, I am now assuming that the java.io.DataOutputStream is actually similar to NSMutableData and the write is appendData. Which means that writeInt is an Endian function and flush is the actual send/sendto command.

Objective-c TCP/IP client

I have a TCP server running on a machine. (implemented in Java). I need to connect to that server from a iPhone and send data to the server and also, receive data on the iphone when server pushes me data. So I need to be notified when data pushes from the server.
Is there a way to do this in Objective C(socket programming). Although I googled I couldn't find a solution. But I saw CFSocket etc.
Please anyone have a solution?
after a possible solutions in the internet, I found a nice asynchronous TCP and UDP socket Library here. (http://code.google.com/p/cocoaasyncsocket). This library worked really well for me so far. This wraps the CFSocket and CFStream.
Thanks for your replies.
You can use the CFNetwork family of classes to implement lower level sockets. Apple has an introduction document that describes the use of these classes.
CFSocket calls and similar will let you create sockets. You can then use CFStreamCreatePairWithSocket() to create a CFReadStreamRef and CFWriteStreamRef, which you can cast to NSInputStream* and NSOutputStream*.

Long polling with NSURLConnection

I'm working on an iPhone application which will use long-polling to send event notifications from the server to the client over HTTP. After opening a connection on the server I'm sending small bits of JSON that represent events, as they occur. I am finding that -[NSURLConnectionDelegate connection:didReceiveData] is not being called until after I close the connection, regardless of the cache settings I use when creating the NSURLRequest. I've verified that the server end is working as expected - the first JSON event will be sent immediately, and subsequent events will be sent over the wire as they occur. Is there a way to use NSURLConnection to receive these events as they occur, or will I need to instead drop down to the CFSocket API?
I'm starting to work on integrating CocoaAsyncSocket, but would prefer to continue using NSURLConnection if possible as it fits much better with the rest of my REST/JSON-based web service structure.
NSURLConnection will buffer the data while it is downloading and give it all back to you in one chunk with the didReceiveData method. The NSURLConnection class can't tell the difference between network lag and an intentional split in the data.
You would either need to use a lower-level network API like CFSocket as you mention (you would have access to each byte as it comes in from the network interface, and could distinguish the two parts of your payload), or you could take a look at a library like CURL and see what types of output buffering/non-buffering there is there.
I ran into this today. I wrote my own class to handle this, which mimics the basic functionality of NSURLConnection.
http://github.com/nall/SZUtilities/blob/master/SZURLConnection.h
It sounds as if you need to flush the socket on the server-side, although it's really difficult to say for sure. If you can't easily change the server to do that, then it may help to sniff the network connection to see when stuff is actually getting sent from the server.
You can use a tool like Wireshark to sniff your network.
Another option for seeing what's getting sent/received to/from the phone is described in the following article:
http://blog.jerodsanto.net/2009/06/sniff-your-iphones-network-traffic/
Good luck!
We're currently doing some R&D to port our StreamLink comet libraries to the iPhone.
I have found that in the emulator you will start to get didReceiveData callbacks once 1KB of data is received. So you can send a junk 1KB block to start getting callbacks. It seems that on the device, however, this doesn't happen. In safari (on device) you need to send 2KB, but using NSURLConnection I too am getting no callbacks. Looks like I may have to take the same approach.
I might also play with multipart-replace and some other more novel headers and mime types to see if it helps stimulate NSURLConnection.
There is another HTTP API Implementation named ASIHttpRequest. It doesn't have the problem stated above and provides a complete toolkit for almost every HTTP feature, including File Uploads, Cookies, Authentication, ...
http://allseeing-i.com/ASIHTTPRequest/