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
Related
I am downloading a bitmap using NSURLConnection. I set the delegate to self, and implement the methods connection:didReceiveData and connectionDidFinishLoading. When data is received, I store it in an NSMutableData object (called input), and then at the end of the connection, I use this to create the bitmap. The problem is that I receive the data in connection:didReceiveData but it is null in connection:DidFinishLoading. How do I fix this?
- (void)start
{
NSURL *url = [NSURL URLWithString:src];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:YES];
}
- (void)connection:(NSURLConnection *)conn
didReceiveData:(NSData *)d
{
NSLog(#"Data Received: %#", d);//This prints the correct data
//Add data chunk to input
[input appendData:d];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
CPLog(#"Finished Receiving bitmap from server. Data received with length %d: %#", [input length], input);//this prints length 0 and a value of (null)
CFDataRef imgData = (__bridge CFDataRef) input;
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData (imgData);
CGImageRef image;
if (!imgDataProvider)
{
NSLog(#"Request Failed!");//happens every time
[callback handleBitmap:nil];
return;
}
image = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
[callback handleBitmap:image];
return;
}
You should allocate memory for input property. Usually it is done before starting new url connection:
- (void)start
{
self.input = [NSMutableData data];
// .... init and start url connection
}
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
Im getting data from a server by executing this code:
- (void) sendGeneral:(NSString *) general{
self.responseData = [NSMutableData data];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:CBURL]];
[request setHTTPMethod:#"POST"];
int i;
i = [general length];
NSLog(#"Length is %i", i);
[request setHTTPBody:[general dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
the data I'm getting after NSLog it to console containing "\r\n" as you can see from the following data (only part of the data to demonstration)
"numberPhoneFrom":"","FormName":"הרשמה\r\n"},{"CallID":314358,"StartDate":"27/07/2011 19:32","TotalTime":51.0,"numberPhoneFrom":"","FormName":"פרטים כלליים\r\n"},{"CallID":424378,"StartDate":"26/09/2011 18:43","TotalTime":63.6,"numberPhoneFrom":"","FormName":"הרשמה\r\n"},{"CallID":311229,"StartDate":"26/07/2011 13:28","TotalTime":18.6,"numberPhoneFrom":"","FormName":"נסיון\r\n"}
Im trying to clean the "\r\n" with all kind of commands but i can't do it this code get the data in the protocol
- (void) GetData: (NSMutableString *)protocol{
[protocol replaceOccurrencesOfString:#"\n" withString:#"" options:0 range:NSMakeRange(0, [protocol length])];
NSLog(#"server data Function%#", protocol);
}
Getting the data back from server in hear in NSMutableString
/*****************************************************************/
/* connection finish loading and continue talk */
/*****************************************************************/
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSMutableString* responseString = [[NSMutableString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// NSLog(#"the Server Response was %#", responseString);
[[self delegate] GetData:responseString];
}
can anyone help?
Probably try this:
[protocol replaceOccurrencesOfString:#"\\r\\n" withString:#"" options:0 range:NSMakeRange(0, [protocol length])];
**Solved this issue on the server, i think this is the best thing to do' servers are much stronger and C# is very good in string handeling
Thank you.**
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 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;