i'm have problem with the writing TCP socket in objective c. i'm having the following error when i then to write a string to my server. some help please?
- error writing to stream <__NSCFOutputStream: 0x102009f0>: Error Domain=NSPOSIXErrorDomain Code=9 "
the following are my code. Thanks inn advance
- (void)setup {
host = // some adderss;
port = // port;
NSURL *url = [NSURL URLWithString:host];
NSLog(@"Setting up connection to %@ : %i", [url absoluteString], port);
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)[url host], port, &readStream, &writeStream);
if(!CFWriteStreamOpen(writeStream)) {
NSLog(@"Error, writeStream not open");
return;
}
[self open];
NSLog(@"Status of outputStream: %i", [outputStream streamStatus]);
return;
}
- (void)open {
NSLog(@"Opening streams.");
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream retain];
[outputStream retain];
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (void)close {
NSLog(@"Closing streams.");
[inputStream close];
[outputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setDelegate:nil];
[outputStream setDelegate:nil];
[inputStream release];
[outputStream release];
inputStream = nil;
outputStream = nil;
}
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
NSLog(@"Stream triggered.");
NSLog(@"dddd%i", event);
switch(event) {
case NSStreamEventHasSpaceAvailable: {
if(stream == outputStream) {
NSLog(@"outputStream is ready.");
NSString *s =@"12";
[self writeOut:s];
}
break;
}
case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) {
NSLog(@"inputStream is ready.");
uint8_t buf[1024];
unsigned int len = 0;
len = [inputStream read:buf maxLength:1024];
if(len > 0) {
NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
[data app开发者_如何学JAVAendBytes: (const void *)buf length:len];
NSString *s = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
[self readIn:s];
[data release];
}
}
break;
}
default: {
NSLog(@"Stream is sending an Event: %i", event);
break;
}
}
}
- (void)readIn:(NSString *)s {
NSLog(@"Reading in the following:");
NSLog(@"%@", s);
}
- (void)writeOut:(NSString *)s {
uint8_t *buf = (uint8_t *)[s UTF8String];
NSInteger nwritten=[outputStream write:buf maxLength:strlen((char *)buf)];
if (-1 == nwritten) {
NSLog(@"Error writing to stream %@: %@", outputStream, [outputStream streamError]);
} else {
NSLog(@"Wrote %ld bytes to stream %@.", (long)nwritten, outputStream);
}
NSLog(@"Writing out the following:");
NSLog(@"%@", s);
Your code actually is all right and works (I tested it). The error you’re getting has error code 9 in the POSIX domain, which is EBADF
(you can look up the posix error codes in /usr/include/sys/errno.h
). EBADF
means you are trying to write to an invalid file descriptor - you didn’t really open the socket.
My guess is that you didn’t show the error. What is the actual value of the string host
? If that’s just the host name or IP address this can’t work, since you are constructing an URL from it and taking the host part of this URL to connect to.
I had this same problem and 2 things solved it for me:
1) waiting until the socket was fully open: I was testing the code out using a Foundation command line tool, which would exit before the socket had a chance to fully open. This was fixed with a simple loop like this:
int i = 0;
while( i++ < 20 )
{
NSLog( @" has space %i, %i", [socket hasSpace], i );
if( ![socket hasSpace] )
continue;
[socket writeOut:@"Hello world"];
break;
}
hasSpace
was simply returning [outputStream hasSpaceAvailable]
2) I was trying to connect to a server using the host NSString*
"localhost"
, when it should have been "http://localhost"
精彩评论