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;
Related
I have an app that uses socket
In my application , i am trying to establish socket connection and after connecting socket i need to send soap request to server.i'm having problem with soap request sending to server. i have attached the code. Please help me in this
BOOL status;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
urlString = #"hoegamestg.hogaming.info";
// urlString = #"247liveagent.hointeractive.com";
if (![urlString isEqualToString:#""])
{
NSURL *website = [NSURL URLWithString:urlString];
if (!website)
{
NSLog(#"%# is not a valid URL", urlString);
status = NO;
}
else
{
NSLog(#"URL IS VALID%#",website );
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef) [website host], 5654, &readStream, &writeStream);
// CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef) urlString, 5654, &readStream, &writeStream);
//USE TOLL-FREE BRIDGING FOR CONVERTING CORE-FOUNDATION STREAMS TO NSSTREAMS.
self.inputStream = (__bridge_transfer NSInputStream *)readStream;
self.outputStream = (__bridge_transfer NSOutputStream *)writeStream;
//SET DELEGATES TO STREAMS.
[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];
//AVOID BLOCKING OPERATIONS BY SCHEDULING THEM ON TO RUN LOOPS.
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//FINALLY OPEN THE STREAMS.
[self.inputStream open];
[self.outputStream open];
}
}......
Delegate method and soap request
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
// Start Logging events.
// NSString *str = [NSString stringWithFormat:#"%d",eventCode];
// NSMutableString *subscribeTableString;
NSData *data;
NSString *soapMessage = [[NSString alloc]init];
switch (eventCode) {
case NSStreamEventNone:
NSLog(#"NSStreamEventNone");
break;
case NSStreamEventOpenCompleted:
NSLog(#"NSStreamEventOpenCompleted");
break;
case NSStreamEventHasBytesAvailable:
NSLog(#"NSStreamEventHasBytesAvailable");
[self readDataFromStream];
break;
case NSStreamEventHasSpaceAvailable:
NSLog(#"NSStreamEventHasSpaceAvailable");
soapMessage=[soapMessage stringByAppendingString:[NSString stringWithFormat:#"<subscribe channel=\"table-bc7ire5oi4uhetfd\" ><player id=\"%#\" />",socketValue ]];
// soapMessage=[soapMessage stringByAppendingString:[NSString stringWithFormat:#"<subscribe channel=\"table-bc7ire5oi4uhetfd\" ><player id= \"c2da1a80c52542dd\" />" ]];
soapMessage =[soapMessage stringByAppendingString:[NSString stringWithFormat:#"<sessionid id=\"%#\"",socketname]];
soapMessage =[soapMessage stringByAppendingString:[NSString stringWithFormat:#"></sessionid></subscribe>"]];
NSLog(#"THE STRING IS : %#", soapMessage);
data = [[NSData alloc] initWithData:[soapMessage dataUsingEncoding:NSASCIIStringEncoding]];
[self.outputStream write:[data bytes] maxLength:[data length]];
NSLog(#"THE STRING IS : %#", self.outputStream);
[self setMWriteData:[NSData dataWithBytes:(__bridge const void*)soapMessage length:
[soapMessage length]]];
[self writeDataToStream];
// <subscribe channel="table-l8i2hq4jo2hjj9ca"><player id="b82fe3c52020494b" /><sessionid id="246421321cc873d080b550bcc555de0e9d9d29d8cba6f243ec56d38c5785"></sessionid></subscribe>
break;
case NSStreamEventErrorOccurred:
NSLog(#"NSStreamEventErrorOccurred");
NSLog(#"THE ERROR IS : %#", [aStream streamError]);
break;
case NSStreamEventEndEncountered:
break;
default:
break;
}
}
If I'm not mistaken, SOAP is based on the HTTP protocol, so you cannot use raw sockets for that. You can refer to this question if you do need SOAP: how to send/recieve soap object with objective c for ipad
However, if you meant simply sending XML over raw sockets, then you'll need to tell the receiver when to stop reading.
HTTP's way of ending streams is adding \r\n\r\n to the end of the string, so you can use that.
Another way is sending a 4 byte header with the amount of bytes to be sent, so add this (untested):
int s = [data length];
NSData *size = [NSData dataWithBytes:&s length:4];
[self.outputStream write:[size bytes] maxLength:[size length]];
before this
[self.outputStream write:[data bytes] maxLength:[data length]];
The server needs to be aware of this and treat every first 4 bytes as the header, and then reading the amount of bytes mentioned in the header.
I think it would be easier to use HTTP's method with the server stopping its reading when it encounters \r\n\r\n
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 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);