I want to convert a UIImage to an NSOutputStream and send it to a server through socket.
#import "Connection.h"
#implementation Connection
-(void) open: (NSString *) h : (int) p
{
strHost = h;
intPort = p;
[NSStream getStreamsToHost:objHost
port:intPort
inputStream:&receiveStream
outputStream:&sendStream];
[receiveStream retain];
[sendStream retain];
[receiveStream setDelegate:self];
[sendStream setDelegate:self];
[receiveStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[sendStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[receiveStream open];
[sendStream open];
printf("Open.\n");
}
- (void) stream: (NSStream *) stream handleEvent: (NSStreamEvent) eventCode
{
printf("EVENT: Start.\n");
switch(eventCode)
{
case NSStreamEventOpenCompleted:
{
printf("EVENT: Open completed.\n");
if(stream == receiveStream)
{
printf("Receiving...\n");
}
if(stream == sendStream)
{
printf("Sending...\n");
NSString * strBuffer = [NSString stringWithFormat:#"GET / HTTP/1.0\r\n\r\n"];
const uint8_t * rawstring = (const uint8_t *)[strBuffer UTF8String];
[sendStream write:rawstring maxLength:strlen(rawstring)];
}
break;
}
case NSStreamEventEndEncountered:
{
printf("EVENT: End encountered.\n");
break;
}
case NSStreamEventHasSpaceAvailable:
{
printf("EVENT: Has space available.\n");
break;
}
case NSStreamEventHasBytesAvailable:
{
printf("EVENT: Has bytes available.\n");
break;
}
case NSStreamEventErrorOccurred:
{
printf("EVENT: Error occurred.\n");
break;
}
case NSStreamEventNone:
{
printf("EVENT: None.\n");
break;
}
}
printf("EVENT: End.\n");
}
-(void) close
{
[receiveStream close];
[sendStream close];
printf("Closed.\n");
}
#end
My question is where can I add code like "sendStream = ..."?
Another question is that I can convert UIImage to NSData using:
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 90);
But how to convert the imageData to NSOutputStream's instance?
My question is where can I add code like "sendStream = ..."?
You're already assigning sendStream with the getStreamsToHost:port:inputStream:outputStream: message. That method returns the two streams by reference.
… how to convert the imageData to NSOutputStream's instance?
You don't need to convert the data to a stream, you need to tell a stream to write the data.
Try NSOutputStream's write:maxLength: method. You'll need to pass the bytes and length from the data object.
Related
How can a connection be closed when the NSOutputStream has finished sending data?
After searching around i have found that the event NSStreamEventEndEncountered is only called if the server drops the connection. not if the OutputStream has finished the data to send.
StreamStatus is Always returning 0 (connection closed) or 2 (connection open) but never 4 (writing data).
since both methods mentioned above are not telling me enough about the write process i am not able to find a way do determine if the Stream is still writing or if it has finished and i can close the connection now.
After 5 days of googleling and trying i am totally out of ideas... Any help appreciated. Thanks
EDIT ADDED CODE AS REQUESTED:
- (void)startSend:(NSString *)filePath
{
BOOL success;
NSURL * url;
assert(filePath != nil);
assert([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
assert( [filePath.pathExtension isEqual:#"png"] || [filePath.pathExtension isEqual:#"jpg"] );
assert(self.networkStream == nil); // don't tap send twice in a row!
assert(self.fileStream == nil); // ditto
// First get and check the URL.
...
....
.....
// If the URL is bogus, let the user know. Otherwise kick off the connection.
...
....
.....
if ( ! success) {
self.statusLabel.text = #"Invalid URL";
} else {
// Open a stream for the file we're going to send. We do not open this stream;
// NSURLConnection will do it for us.
self.fileStream = [NSInputStream inputStreamWithFileAtPath:filePath];
assert(self.fileStream != nil);
[self.fileStream open];
// Open a CFFTPStream for the URL.
self.networkStream = CFBridgingRelease(
CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) url)
);
assert(self.networkStream != nil);
if ([self.usernameText.text length] != 0) {
success = [self.networkStream setProperty:self.usernameText.text forKey:(id)kCFStreamPropertyFTPUserName];
assert(success);
success = [self.networkStream setProperty:self.passwordText.text forKey:(id)kCFStreamPropertyFTPPassword];
assert(success);
}
self.networkStream.delegate = self;
[self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
///////******** LINE ADDED BY ME TO DISONNECT FROM FTP AFTER CLOSING CONNECTION *********////////////
[self.networkStream setProperty:(id)kCFBooleanFalse forKey:(id)kCFStreamPropertyFTPAttemptPersistentConnection];
///////******** END LINE ADDED BY ME *********////////////
[self.networkStream open];
// Tell the UI we're sending.
[self sendDidStart];
}
}
- (void)stopSendWithStatus:(NSString *)statusString
{
if (self.networkStream != nil) {
[self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.networkStream.delegate = nil;
[self.networkStream close];
self.networkStream = nil;
}
if (self.fileStream != nil) {
[self.fileStream close];
self.fileStream = nil;
}
[self sendDidStopWithStatus:statusString];
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
// An NSStream delegate callback that's called when events happen on our
// network stream.
{
#pragma unused(aStream)
assert(aStream == self.networkStream);
switch (eventCode) {
case NSStreamEventOpenCompleted: {
[self updateStatus:#"Opened connection"];
} break;
case NSStreamEventHasBytesAvailable: {
assert(NO); // should never happen for the output stream
} break;
case NSStreamEventHasSpaceAvailable: {
[self updateStatus:#"Sending"];
// If we don't have any data buffered, go read the next chunk of data.
if (self.bufferOffset == self.bufferLimit) {
NSInteger bytesRead;
bytesRead = [self.fileStream read:self.buffer maxLength:kSendBufferSize];
if (bytesRead == -1) {
[self stopSendWithStatus:#"File read error"];
} else if (bytesRead == 0) {
[self stopSendWithStatus:nil];
} else {
self.bufferOffset = 0;
self.bufferLimit = bytesRead;
}
}
// If we're not out of data completely, send the next chunk.
if (self.bufferOffset != self.bufferLimit) {
NSInteger bytesWritten;
bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
assert(bytesWritten != 0);
if (bytesWritten == -1) {
[self stopSendWithStatus:#"Network write error"];
} else {
self.bufferOffset += bytesWritten;
}
}
} break;
case NSStreamEventErrorOccurred: {
[self stopSendWithStatus:#"Stream open error"];
} break;
case NSStreamEventEndEncountered: {
// FOR WHATEVER REASON THIS IS NEVER CALLED!!!!
} break;
default: {
assert(NO);
} break;
}
}
There can be two interpretations to your question. If what you are asking is "I have a NSOutputStream and I'm finished writing to it how do I signal this?" then the answer is as simple as call the close method on it.
Alternately, If what you are really saying is "I have a NSInputStream and I want to know when I've reached the end-of-stream" then you can look at hasBytesAvailable or streamStatus == NSStreamStatusAtEnd.
For your information, to actually get the status NSStreamStatusWriting you would need to be calling the streamStatus method from another thread while this thread is calling write:maxLength:.
--- Edit: Code Suggestion
The reason you would never get notified is that an output stream is never finished (unless it's a fixed size stream, which an FTP stream is not). It's the input stream that gets "finished" at which point you can close your output stream. That's the answer to your original question.
As a further suggestion, I would skip run loop scheduling and the "event processing" except for handling errors on the output stream. Then I would put the read/write code into a NSOperation subclass and send it off into a NSOperationQueue. By keeping a reference to the NSOperations in that queue you would be able to cancel them easily and even show a progress bar by adding a percentComplete property. I've tested the code below and it works. Replace my memory output stream with your FTP output stream. You will notice that I have skipped the validations, which you should keep of course. They should probably be done outside the NSOperation to make it easier to query the user.
#interface NSSendFileOperation : NSOperation<NSStreamDelegate> {
NSInputStream *_inputStream;
NSOutputStream *_outputStream;
uint8_t *_buffer;
}
#property (copy) NSString* sourceFilePath;
#property (copy) NSString* targetFilePath;
#property (copy) NSString* username;
#property (copy) NSString* password;
#end
#implementation NSSendFileOperation
- (void) main
{
static int kBufferSize = 4096;
_inputStream = [NSInputStream inputStreamWithFileAtPath:self.sourceFilePath];
_outputStream = [NSOutputStream outputStreamToMemory];
_outputStream.delegate = self;
[_inputStream open];
[_outputStream open];
_buffer = calloc(1, kBufferSize);
while (_inputStream.hasBytesAvailable) {
NSInteger bytesRead = [_inputStream read:_buffer maxLength:kBufferSize];
if (bytesRead > 0) {
[_outputStream write:_buffer maxLength:bytesRead];
NSLog(#"Wrote %ld bytes to output stream",bytesRead);
}
}
NSData *outputData = [_outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
NSLog(#"Wrote a total of %lu bytes to output stream.", outputData.length);
free(_buffer);
_buffer = NULL;
[_outputStream close];
[_inputStream close];
}
- (void) stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
// Handle output stream errors such as disconnections here
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
NSOperationQueue *sendQueue = [[NSOperationQueue alloc] init];
NSSendFileOperation *sendOp = [[NSSendFileOperation alloc] init];
sendOp.username = #"test";
sendOp.password = #"test";
sendOp.sourceFilePath = #"/Users/eric/bin/data/english-words.txt";
sendOp.targetFilePath = #"/Users/eric/Desktop/english-words.txt";
[sendQueue addOperation:sendOp];
[sendQueue waitUntilAllOperationsAreFinished];
}
return 0;
}
What I am trying to do: I have a url request (post) where I send some information to a api server which then starts streaming data in bytes to me.
1) How do I post data when trying to set up a stream as right now I am just using a url, can I incorporate a NSURLRequest some how?
2) Why isnt my stream even opening (streamStatus returns 0) and thus - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode never being called? , this is my best attempt and for the most part following this Guide
- (void)setUpStreamFromURL:(NSURL *)path {
// iStream is NSInputStream instance variable
iStream = [[NSInputStream alloc] initWithURL:path];
[iStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[iStream open];
NSLog(#"Stream Open: %lu",[iStream streamStatus]); //return 0
}
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
NSLog(#"Streaming");
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if(!_data) {
_data = [[NSMutableData data] init];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if(len) {
[_data appendBytes:(const void *)buf length:len];
NSLog(#"DATA BEING SENT : %#", _data);
// bytesRead is an instance variable of type NSNumber.
// [bytesRead setIntValue:[bytesRead intValue]+len]; //getting error that setInt value is not part of NSNumber, and thats true so not sure what to do about it, but this isn't the issue.
} else {
NSLog(#"no buffer!");
}
break;
}
case NSStreamEventEndEncountered:
{
[stream close];
[stream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
stream = nil; // stream is ivar, so reinit it
break;
}
// continued ...
}
}
also incase it helps, my header file:
#import <Foundation/Foundation.h>
#import "Login.h"
#interface Stream : NSStream <NSStreamDelegate> {
NSMutableArray *searchIdList;
NSInputStream *iStream;
NSNumber *bytesRead;
}
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode ;
-(id)initWithLoginObject:(Login *)log;
#property NSMutableData *data;
#end
You can't use NSURLRequest in Stream.
To create a request you can use this.
request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("POST"),(CFURLRef) url, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("User-Agent"), CFSTR("MSControl-US"));
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), CFSTR("application/json"));
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Connection"), CFSTR("Keep-Alive"));
After that you can create the stream using
readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request)
or if you already have an opened stream you can serialize your request With :
NSData *data = (NSData *)CFHTTPMessageCopySerializedMessage(request);
and send with This:
length = [data length];
CFWriteStreamWrite((CFWriteStreamRef)outStream,data,lenght);
Hope this help
i have written code for reading data from tcp port 3000
- (BOOL)connect
{
int cIter = 0;
while(cIter++<5)
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
#try{
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)M_CONNECT_HOST, M_CONNECT_PORT, &readStream, &writeStream);
}
#catch (NSException *ex) {
}
if(readStream!=nil && writeStream!=nil)
{
m_sin = (__bridge NSInputStream *)readStream;
m_sout = (__bridge NSOutputStream *)writeStream;
[m_sin setDelegate:self];
[m_sout setDelegate:self];
[m_sin scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[m_sout scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[m_sin open];
[m_sout open];
return true;
}
}
return false;
}
When i write to tcp output stream its working but when i try to read from the tcp input stream its not reading i mean my
[m_sin read:t maxlength:10];
is always returning -1 (where m_sin is my input stream)
And i m passing the data to the tcp port by terminal
please Help me
Implement the handleEvent and check it out the eventCode
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(#"stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (aStream == inputStream) {
// read it in
unsigned int len = 0;
len = [inputStream read:buf maxLength:1019];
buf[len] = '\0';
if(!len) {
if ([aStream streamStatus] != NSStreamStatusAtEnd){
NSLog(#"Failed reading data from peer");
}
} else {
//I am reading UIImage here
NSData *data = [NSData dataWithBytes:(const void *)buf length:1019];
UIImage *image = [UIImage imageWithData:data];
self.transferedimage.image = image;
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(#"stream ErrorOccurred");
break;
case NSStreamEventEndEncountered:
NSLog(#"stream EndEncountered");
break;
default:
NSLog(#"stream UnKnown");
break;
}
}
I press the button to connect to the server (TCP), but i don't know whether it connected or not..
Here is that part of the code:
[self connectToServerUsingCFStream:msg portNo:50000];
if(readStream && writeStream)
{
NSString *newText = [[NSString alloc] initWithFormat:#"Connected!! :)"];
statusText.text = newText;
[newText release];
pingButton.hidden = NO;
}
else
{
NSString *newText = [[NSString alloc] initWithFormat:#"Connection unsuccessful :("];
statusText.text = newText;
[newText release];
}
I always get the "Connected!! :)" even if the server is offline :s
The solution for people following the connection method:
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(CFStringRef) urlStr,
portNo,
&readStream,
&writeStream);
if (readStream && writeStream)
{
CFReadStreamSetProperty(readStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
iStream = (NSInputStream *)readStream;
[iStream retain];
[iStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[iStream open];
oStream = (NSOutputStream *)writeStream;
[oStream retain];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream open];
}
is using the
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
like this:
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *io;
if (theStream == iStream) io = #">>";
else io = #"<<";
NSString *event;
switch (streamEvent)
{
case NSStreamEventNone:
event = #"NSStreamEventNone";
statusText.text = #"Can not connect to the host!";
break;
case NSStreamEventOpenCompleted:
event = #"NSStreamEventOpenCompleted";
pingButton.hidden = NO;
statusText.text = #"Connected";
break;
case NSStreamEventHasBytesAvailable:
event = #"NSStreamEventHasBytesAvailable";
if (theStream == iStream)
{
//read data
uint8_t buffer[1024];
int len;
while ([iStream hasBytesAvailable])
{
len = [iStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
NSData *theData = [[NSData alloc] initWithBytes:buffer length:len];
if (nil != output)
{
//do something with data
}
}
}
}
break;
case NSStreamEventHasSpaceAvailable:
event = #"NSStreamEventHasSpaceAvailable";
if (theStream == oStream)
{
//send data
uint8_t buffer[11] = "I send this";
int len;
len = [oStream write:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSLog(#"Command send");
[oStream close];
}
}
break;
case NSStreamEventErrorOccurred:
event = #"NSStreamEventErrorOccurred";
statusText.text = #"Can not connect to the host!";
pingButton.hidden = YES;
break;
case NSStreamEventEndEncountered:
event = #"NSStreamEventEndEncountered";
statusText.text = #"Connection closed by the server.";
pingButton.hidden = YES;
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[theStream release];
theStream = nil;
break;
default:
event = #"** Unknown";
}
NSLog(#"%# : %#", io, event);
}
(for all I know!) The credits go to deksa from this post (though i don't know who was the creator, because i've seen this some times on the web, including here o SO). This code was slightly modified by me (pingButton, statusText), if you want the original one go to the link previously mentioned.
The Apple Developer Site has some info on this as well.
Like i've said, I had seen some stuff looking like this on the web, but now i understand that everything that happens after you connect is "automatic"; for instance, if the server is on hold with a read(), the case NSStreamEventHasSpaceAvailable: will be called automatically, and all the code in there will be run.
Now I consider this question answered.
Although you did not provide enough informations, I'd suggest to use ASIHTTPRequest for HTTP, and AsyncSocket for TCP and UDP. If an connection was established, callback methods will be triggered,
I have to say, that my experiences with CFNetwork are very limited, but for me it seems, as if you are just testing, if stream objects exists (if(readStream && writeStream)).
A quick look at CFNetwork Programming Guide: Working with Read Streams tells me, that you have to open it with CFReadStreamOpen(), this function will return an boolean, if it really did open the stream.
if (!CFReadStreamOpen(myReadStream)) {
CFStreamError myErr = CFReadStreamGetError(myReadStream);
// An error has occurred.
if (myErr.domain == kCFStreamErrorDomainPOSIX) {
// Interpret myErr.error as a UNIX errno.
} else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) {
// Interpret myErr.error as a MacOS error code.
OSStatus macError = (OSStatus)myErr.error;
// Check other error domains.
}
}
BTW:
instead of
NSString *newText = [[NSString alloc] initWithFormat:#"Connected!! :)"];
statusText.text = newText;
[newText release];
you just can write statusText.text = #"Connected!! :)";
I'm trying to use the NSStream objects to open and then write and read on a socket but i have a problem.
I don't know how to write on the socket, after i have opened it.
Here is how i have done
1) first openning the socket :
NSURL *website = [NSURL URLWithString:urlStr];
if (!website) {
NSLog(#"%# is not a valid URL");
return;
}
NSHost *host = [NSHost hostWithName:urlStr];
// iStream and oStream are instance variables
[NSStream getStreamsToHost:host port:6667 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];
2) Set the loop :
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *io;
if (theStream == iStream) io = #">>";
else io = #"<<";
NSLog(#"stream : %#",theStream);
NSString *event;
switch (streamEvent)
{
case NSStreamEventNone:
event = #"NSStreamEventNone";
break;
case NSStreamEventOpenCompleted:
event = #"NSStreamEventOpenCompleted";
break;
case NSStreamEventHasBytesAvailable:{
event = #"NSStreamEventHasBytesAvailables";
if (theStream == iStream)
{
if(!_data) {
_data = [[NSMutableData data] retain];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [iStream read:buf maxLength:1024];
NSLog(#"Lenght data read : %d", len);
if(len) {
NSData * dataReceived= [[NSString stringWithFormat:#"%s\n", (char *)buf] dataUsingEncoding:NSUTF8StringEncoding];
NSString *s = [[NSString alloc] initWithData:dataReceived encoding:NSUTF8StringEncoding];
NSLog(#"Received _data: \"%#\"\n",s);
} else {
NSLog(#"nothing to read!");
}
}else {
NSLog(#"Not the good stream");
}
break;
}
case NSStreamEventHasSpaceAvailable:{
event = #"NSStreamEventHasSpaceAvailable";
if (theStream == oStream )
{
if(isConnexionCommandSent == NO){
[self sendCommand:#"My connection command"];
isConnexionCommandSent = YES;
}
}
break;
}
case NSStreamEventErrorOccurred:
event = #"NSStreamEventErrorOccurred";
NSError *theError = [theStream streamError];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[theError localizedDescription]
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
break;
case NSStreamEventEndEncountered:
event = #"NSStreamEventEndEncountered";
break;
default:
event = #"** Unknown";
}
NSLog(#"%# : %#", io, event);
}
3) then i have a function that is called when I touch a button
- (IBAction)join:(id)sender{
if([oStream hasSpaceAvailable]){
NSLog(#"iStream Status : %d",[iStream streamStatus]);
NSLog(#"oStream Status : %d",[oStream streamStatus]);
[self sendCommand:#"join"];
}else{
NSLog(#"Error command can't be sent");
}
}
-(void) sendCommand:(NSString *) command{
NSLog(#"space : %d",[oStream hasSpaceAvailable]);
if ([oStream hasSpaceAvailable])
{
NSLog(#"Command writen : %s\n",[command cStringUsingEncoding:NSASCIIStringEncoding]);
NSInteger i=[oStream write:(const uint8_t *)[command cStringUsingEncoding:NSASCIIStringEncoding] maxLength:(NSInteger)[command lengthOfBytesUsingEncoding:NSASCIIStringEncoding]];
if (i<0)
{
NSLog(#"erreur lors de l'envoi, status:%i, erreur:%#", [oStream streamStatus], [oStream streamError]);
}
isReadyToSend = NO;
}
else
{
NSLog(#"impossible d'envoyer, status:%i, erreur:%#", [oStream streamStatus], [oStream streamError]);
}
}
But the problem is that when the function join is called, everything goes fine, but the server receives nothing ...
On
NSInteger i=[oStream write:(const uint8_t *)[command cStringUsingEncoding:NSASCIIStringEncoding] maxLength:(NSInteger)[command lengthOfBytesUsingEncoding:NSASCIIStringEncoding]];
i is > 0, so i assume that the writing went well, but on the server nothing is received ... i don't know why ...
Can you help me?
Hey #Ptitaw see this post. I believe there you might find your answer and an easier way to connect and get access automatically to all events (reading, writing, etc..)
Hope I could help :)
A Very very late answer, however, it might be helpful to someone having similar issue.
I think it may be due to data encoding mechanism. Your server might be using UTF-8 encoding and you are sending your data using NSASCIIStringEncoding. Try this:
NSInteger i=[oStream write:(const uint8_t *)[command cStringUsingEncoding:NSUTF8StringEncoding] maxLength:(NSInteger)[command lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];