2

所以我想做的就是向 url 发送一个 POST 请求。现在我尝试使用 NSURLRequest/NSURLConnection,但遇到问题并决定移到较低级别,也是因为我想发送大文件并认为直接处理流可能会更好。但是输出流委托似乎从未被调用,而且我似乎无法找到使用 NSOutputStream 的示例initWithURL

NSURL *url = [NSURL URLWithString:NSString stringWithFormat: @"http://url"];
self.outputStream = [[NSOutputStream alloc] initWithURL:url append:NO];
[outputStream retain];
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream open];

似乎在 init 之后 outputStream 为空,我无法理解,因为我的 url 是一个有效的 url——我可以从终端 ping 它并从其他来源发送数据。我做错了什么,或者谁能告诉我如何使用流向 URL 写入 POST 请求?谢谢。

4

2 回答 2

3

您不能用于NSOutputStream向 HTTP 服务器发送 POST 请求。

好的方法是创建一个NSMutableURLRequest并为该请求提供一个HTTPBodyStream然后创建一个NSURLConnection来发送请求。

HTTPBodyStream是一个NSInputStream请求将从中读取正文。您可以使用NSData对象或文件的内容对其进行初始化。

如果您想提供自定义内容(例如,您想上传文件作为multipart/form-data请求的一部分),您可能需要子类化NSInputStream. 在这种情况下,我建议您查看如何实现 CoreFoundation 免费桥接 NSInputStream 子类,它解释了如何解决使用自定义输入流时出现的问题NSURLConnection。或者您可以使用ASIHTTPRequest,它提供开箱即用的多部分 HTTP 请求。

于 2012-06-26T14:36:18.247 回答
0

是的,您可以使用 NSOutputStream 发送 HTTP GET/POST 请求。

1.make & 打开你的流。

2.当流准备好写入时,NSStreamEventHasSpaceAvailable事件将在方法中发送:

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode

https://developer.apple.com/documentation/foundation/nsstreamdelegate/1410079-stream?language=objc

3.制作一个CFHTTPMessageRef&并写入数据。

像这样的代码:

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
    switch (eventCode) {
    case NSStreamEventOpenCompleted:{
        // 
    }
        break;
    case NSStreamEventHasSpaceAvailable:{
        [self sendHTTPMessage];
    }
        break;
    default:{
        //
    }
        break;
}

- (void)sendHTTPMessage{
    //create a http GET message
    CFStringRef requestMethod = (CFStringRef)CFAutorelease(CFSTR("GET"));
    CFHTTPMessageRef httpRequest = (CFHTTPMessageRef)CFAutorelease(CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, (__bridge  CFURLRef)yourURL,kCFHTTPVersion1_1));
    //set HTTP header
    CFHTTPMessageSetHeaderFieldValue(httpRequest, (__bridge CFStringRef)@"Host", (__bridge CFStringRef)@"yourhost.com");
    CFHTTPMessageSetHeaderFieldValue(httpRequest, (__bridge CFStringRef)@"Connection", (__bridge CFStringRef)@"close");
    //set HTTP Body
    ...
    //let's send it
    CFDataRef serializedRequest = CFHTTPMessageCopySerializedMessage(httpRequest);
    NSData *requestData = (__bridge_transfer NSData *)serializedRequest;
    [self.outStream write:requestData.bytes maxLength:requestData.length];
    [self.outStream close];
}

请记住,关键是将 CFHTTPMessageRef 转换为要写入的字节。

于 2020-04-16T11:49:44.570 回答