iPhone communication using Sockets [closed] - iphone

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).

Related

How to reuse and share an HTTP connection between multiple threads in iOS?

In an IPhone app, I want to create a connection, have the user log in to a webservice once, and then have all subsequent requests by multiple threads reuse the authorized connection. What is the best way to implement this in iOS?
FYI: I have implemented this previously in an Android app by using Apache HTTPClient with a threadSafeConnectionManager whereby whenever you need a connection, you ask the shared httpClient for one and it dispatches one from the pool it maintains; all connections retain the same authentication credentials. I am looking for the comparable way to do this in an IPhone app.
I don't know of any built in mechanism for this, but you could fork ASIHttpRequest and bend it to your will. It shouldn't take much effort to refactor the authentication part from a shared location, but your concept of reusing the TCP socket may take a bit of work. There probably isn't a way of doing it with NSURLRequest, but since ASIHttpRequest uses the core foundation methods, that is not an issue.

NSURLConnection, using proxy server

I want to POST using an NSURLConnection, using a SOCKS proxy along the way.
From what I've read, NSURLConnection does support SOCKS and HTTP proxies. The question is, where do I configure it?
I couldn't find any suitable method on e.g. NSURLRequest for configuring which proxy server to use.
If this is a limitation, does anyone know of a good replacement that does support SOCKS?
Though I've never used it myself, from reading around the topic I think you need to use an NSOutputStream rather than an NSURLConnection, which is toll-free bridged with CFWriteStream. On that you can use CFWriteStreamSetProperty with the kCFStreamPropertySOCKSProxy key and a dictionary with corresponding entries for the various keys defined here.

How to use sockets in iOS?

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

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/

COMET (server push to client) on iPhone [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 4 years ago.
Improve this question
I'm looking to establish some kind of socket/COMET type functionality from my server(s) to my iPhone application. Essentially, anytime a user manages to set an arbitrary object 'dirty' on the server, by say, updating their Address.. the feedback should be pushed from the server to any clients keeping a live poll to the server. The buzzword for this is COMET I suppose. I know there is DWR out there for web browser applications, so I'm thinking, maybe it's best to set a hidden UIWebView in each of my controllers just so I can get out of the box COMET from their javascript framework? Is there a more elegant approach?
There are a couple of solutions available to use a STOMP client.
STOMP is incredibly simple and lightweight, perfect for the iPhone.
I used this one as my starting point, and found it very good. It has a few object allocation/memory leak problems, but once I got the hang of iPhone programming, these were easy to iron out.
Hope that helps!
Can you use ordinary TCP/IP socket in your application?
A) If yes then definitely a raw TCP/IP socket is more elegant solution. From your iPhone app you just wait for notification events. The socket is open as long as your application is open. If you want you can even use HTTP protocol / headers.
On the server side you can use some framework to write servers which efficiently handle thousands of open TCP/IP connections. e.g Twisted, EventMachine or libevent. Then just bind the server main socket to http port (80).
The idea is to use a server which keeps just a single data structure per client. Receives update event from some DB application and then pushes it to right client.
B) No, you have to use Apache and http client on iPhone side. Then you should know that whole COMET solution is in fact work around for limitations of HTTP protocol and Apache / PHP.
Apache was designed to handle many short time connections. As far I know only newest versions Apache (mpm worker) can handle efficiently big number of opened connection. Previously Apache was keeping one process per connection.
Web browsers have a limit of concurrent open connections to one web server (URL address in fact, eg. www.foo.com, not IP address of www.foo.com). And the limit is 2 connections. Additionally, a browser will allow only for AJAX connections to the same server from which the main HTML page was downloaded.
I wrote a web server for doing exactly this kind of thing. I'm pushing realtime updates through the server with long polling and, as an example, I had safari on the iPhone displaying that data.
A given instance of the server should be able to handle a few thousand concurrent clients without trying too hard. I've got a plan to put them in a hierarchy to allow for more horizontal scaling (should be quite trivial, but doesn't affect my current application).
WebSync has a javascript client that works on the iPhone, if that's what you're after
Would long-polling work for what you want to achieve? You can implement the client-side in a few lines of regular Javascript, which will be lighter than any framework could possibly be.
It would also be trivial to implement it in ObjC (connect, wait for a response or timeout, repeat)
The answers to my question Simple "Long Polling" example code? hopefully explain how extremely simple Long Polling is..
Basically you would just request a URL as usual - the web-server would accept the connection, but not send any data until it's available. When you receive data, or the connection times-out, you reconnect (and repeat)
The most complicated bit would be server server-side, as you cannot use a regular threaded web-server like Apache, although this is also the case with Comet..
StreamHub Comet Server works with the iPhone out of the box, no plugins or anything required. Just browsed to their website on my iPhone and all the examples worked, didn't need to install Flash or anything.
Do you want/have do the communication for your app over http? If not, you can use CFNetwork framework to use sockets (TCP/UDP) to allow your app and server to communicate. From what I have seen of the CFNetwork stack, it is pretty cool, and makes it fairly straitforward to read and write to streams, and allows for synchronous and asynchronous communication. It also allows for you to define callbacks on your socket allowing you to get notified of events like data received, connection made, etc. So, in your example you could send the information over the socket to your server, and then you could define a callback that would listen for incoming data on the stream and then update your app accordingly.
EDIT: Did a little more research, and if you go the socket approach, you may want to also look at the NSStream classes. They are Cocoa abstractions build on top of the CFSocket stuff.
you didn't mention what serverside tech you're using. But in case it's microsoft .net (or for any other googlers who come across this), there is a simple option for comet: http://www.codeplex.com/ncomet.
COMET, LightStreamer, AJAX all that junk is broken. It is basics of TCP that no 'keep-alives' are ever guaranteed without pinging traffic.. So you can forget that long-polling if any decent reliability or timely delivery is to be guaranteed..
It's just hype everyone saw through back in 2003 when the lame-mania kicked off..