I want to write an NSOutputStream to a server with apple's sample code:
NSURL *website = [NSURL URLWithString:str_IP];
NSHost *host = [NSHost hostWithName:[website host]];
[NSStream getStreamsToHost:host port:1100 inputStream:nil outputStream:&oStream];
[oStream retain];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream open];
These codes works well on the iPhone simulator, but when I build it to real device. Two warnings pop up. The problem is:
1)class NSHost doesn't belong to iphone os library
2)getStreamsToHost is not found either
Any suggestions for the alternative method or class which can be used on real device?
Since CFWriteStream is toll-free bridged to NSOutputStream you can use CFStreamCreatePairWithSocketToHost to get your stream pair:
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)host, port, &readStream, &writeStream);
if (readStream && writeStream) {
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
inputStream = (NSInputStream *)readStream;
[inputStream retain];
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
outputStream = (NSOutputStream *)writeStream;
[outputStream retain];
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream open];
}
if (readStream)
CFRelease(readStream);
if (writeStream)
CFRelease(writeStream);
Related
Am working on an iPhone App which fetches an image from a URL. I was using 'NSData dataWithContentsOfUrl] & it worked fine.
But then, as you might have guessed, the request is synchronous.
I want the request to be asynchronous. So, I tried using the NSURLConnection's sendAsynchronousRequest() call. But this returns the following error in the method 'didFailWithError' :
Error Domain=kCFErrorDomainCFNetwork Code=310 "There was a problem
communicating with the secure web proxy server (HTTPS).
Can someone please help?
This is my NSURLConnection code snippet:
NSURL *url = [NSURL URLWithString:notePicUrl];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:100.0];
//NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSURLConnection* _connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:NO];
self.port = [NSPort port];
self.runLoop = [NSRunLoop currentRunLoop];
[self.runLoop addPort:self.port forMode:NSDefaultRunLoopMode];
[_connection scheduleInRunLoop:self.runLoop forMode:NSDefaultRunLoopMode];
[_connection start];
while (self.finished != YES ) {
[self.runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 0.1]];
}
[self.runLoop removePort:[self port] forMode:NSDefaultRunLoopMode];
[_connection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
And the NSURLConnectionDelegate methods (not yet implemented ; just testing to first see if it works) ...
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
NSLog(#"didReceiveResponse");
//_data = [[NSMutableData alloc] init]; // _data being an ivar
}
-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
NSLog(#"didReceiveData");
//[_data appendData:data];
}
-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(#"didFailWithError %#", [error description]);
// Handle the error properly
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(#"connectionDidFinishLoading");
//[self handleDownloadedData]; // Deal with the data
}
I just fixed this ; I tried using the simple code line:
[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];
And then handling the data in the Delegate methods. Earlier, it was attempting to run in a separate thread. this works just fine & is asynchronous.
I am trying to open a socket connection from my iphone simulator and send a simple NSString to a localhost server I set up with java in port 80.
The problem that I have is that when I write data on the NSOutputStream its not being received by the server until I close the simulator. And then the server receives the data and this exception is thrown java.net.SocketException: Broken pipe
I know is something related with closing the NSOutputStream and flushing, but how can I achieve this in Objective c?
I call the ProtocolCommunication in my initial ViewController like this:
protocol = [[ProtocolCommunication alloc] init];
[protocol initNetworkCommunication];
[protocol sendData];
ProtocolCommunication class (IOS)
#implementation ProtocolCommunication
#synthesize inputStream, outputStream
- (void) initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)#"localhost", 80, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
//do the Looping
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
NSLog(#"INIT COMPLETE");
}
- (void) sendData {
NSString *response = #"HELLO from my iphone";
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
}
Java Server
String msgReceived;
try {
ServerSocket serverSocket = new ServerSocket(80);
System.out.println("RUNNING SERVER");
while (running) {
Socket connectionSocket = serverSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
msgReceived = inFromClient.readLine();
System.out.println("Received: " + msgReceived);
outToClient.writeBytes("Aloha from server");
outToClient.flush();
outToClient.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Any Ideas??
I solved it by just adding \n to the NSString like this:
NSString *response = #"HELLO from my iphone \n"; // This flushes the NSOutputStream so becarefull everyone
I successfully open a socket to send data to it.When i tried to send an image it crashed and when i send string to it it works fine.I am converting an image to data and then put this data into the string that has to be send to server.
Need guidance, please help
Below is the code , i am using to connect with stream.
NSString *urlStr = #"http://182.71.22.107:1935/VideoCalling/5d14a9bc-b816-4c82-bbb7-623d18243a02.sdp/playlist.m3u8";
if (![urlStr isEqualToString:#""])
{
NSURL *website = [NSURL URLWithString:urlStr];
if (!website)
{
NSLog(#"%# is not a valid URL");
return;
}
NSHost *host = [NSHost hostWithName:[website host]];
// iStream and oStream are instance variables
[NSStream getStreamsToHost:host port:8081 inputStream:&iStream outputStream:&oStream];
[iStream retain];
[oStream retain];
[iStream setDelegate:self];
[oStream setDelegate:self];
NSData *data = UIImageJPEGRepresentation([UIImage imageNamed:#"abc.png"], 90);
// Convert from host to network endianness
uint32_t length = (uint32_t)htonl([data length]);
// Don't forget to check the return value of 'write'
[oStream write:(uint8_t *)&length maxLength:4];
[oStream write:[data bytes] maxLength:length];//writes to stream
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[iStream open];
[oStream open];
}
Here i write to stream
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
int byteIndex;
switch(eventCode) {
case NSStreamEventHasSpaceAvailable:{
if (stream == oStream) {
//NSString * str = [NSString stringWithFormat:#"sdsdfdfggghhfhfh"];
NSString * str = [[NSString alloc]initWithData:datap encoding:NSUTF16StringEncoding];
NSLog(#"%#,lenght===%d",str,[str length]);
const uint8_t * rawstring = (const uint8_t *)[str UTF8String];
[oStream write:rawstring maxLength:strlen(15)];
[oStream close];
}
UIAlertView *a = [[UIAlertView alloc]initWithTitle:#"h" message:#"Available" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil];
[a show];
[a release];
}
break;
Try this sample by apple developer in PostController
I am a beginner in objective c and iphone programming. I'm making a program for transfering files from iphone to server through gprs. I dont know that how can i pick a file from the desktop to load into the simulator and then sending the file to the server.please explain that how can i pick such file and i also dont know how to access the path of a file in a mac operating system. Can the following code be useful in picking up a file
NSString *urlStr = #"192.168.178.26";
if (![urlStr isEqualToString:#""]) {
NSURL *website = [NSURL URLWithString:urlStr];
if (!website) {
NSLog(#"%# is not a valid URL");
return;
}
NSHost *host = [NSHost hostWithName:[website host]];
[NSStream getStreamsToHost:host port:3258 inputStream:&iStream outputStream:&oStream];
[iStream retain];
[oStream retain];
[iStream setDelegate:self];
[oStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[iStream open];
[oStream open];
You will need to look at using Documents path and saving items into the phone/simulators app documents folder (ios does not support user created subfolders so the hierarchies are pretty flat, exceptions being there are a few predefined places on the ios you can put files)
Examples below read/write to ios file system. You would need to transport that somehow client/server.
//ensure whatever object you pass in has the writeToFile method or this will crash. UIImage need to use UIImagePNGRepresentation or similar.
+ (void)writeToFile:(id)object withFileName:(NSString*)filename
{
[object writeToFile:[[MyAppDelegate DocumentsPath] stringByAppendingPathComponent:filename] atomically:TRUE];
}
+ (NSData*)readFromFile:(NSString*)filename
{
NSString* path = [[MyAppDelegate DocumentsPath] stringByAppendingPathComponent:filename];
if ([[NSFileManager defaultManager] fileExistsAtPath:path])
{
return [NSData dataWithContentsOfFile:path];
}
return nil;
}
You can add your test file to the project as a resource.
I want to establish socket connection to streaming server (with iphone ) and want to download its content like image,.css,etc to iphone. Any Idea or sample code is can help me. I need to write code for client only.
Establish Connection as follows and change the urlStr to your server URL
NSString *urlStr = #"http://192.168.0.108";
NSURL *website = [NSURL URLWithString:urlStr];
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)[website host], 1234, &readStream, &writeStream);
NSInputStream *inputStream = (NSInputStream *)readStream;
NSOutputStream *outputStream = (NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
Make Use of NSStream Delegate as follows to read data
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
NSLog(#"Bytes Available");
uint8_t b[1024];
unsigned int len = 0;
NSMutableData *data = [[NSMutableData alloc] init];
len = [(NSInputStream *)stream read:b maxLength:1024];
if(!len) {
if ([stream streamStatus] != NSStreamStatusAtEnd)
{
}
} else {
[data appendBytes:(const void *)b length:len];
int bytesRead;
bytesRead += len;
//make use of data here
}
}
break;
}
}
Slightly changes in the code I used:
NSHost *host = [NSHost hostWithName:[website host]];
[NSStream getStreamsToHost:host
port:8766
inputStream:iStream
outputStream:oStream];
Instead of
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)[website host], 1234, &readStream, &writeStream);
NSInputStream *inputStream = (NSInputStream *)readStream;
NSOutputStream *outputStream = (NSOutputStream *)writeStream;