@Rob Napier @Eric Nelson Như bạn đã đề cập: "NSURLConnection đủ thông minh để xử lý việc này cho bạn bằng cách sử dụng HTTP/1.1 và sử dụng lại các kết nối hiện có". Tuy nhiên, tôi không thể tìm thấy mô tả như vậy trong bất kỳ tài liệu nào của Apple về điều đó.
Để thực hiện điều rõ ràng, tôi viết một số mã để kiểm tra nó:
- (IBAction)onClickSend:(id)sender {
[self sendOneRequest];
}
-(void)sendOneRequest {
NSURL *url = [NSURL URLWithString:@"http://192.168.1.100:1234"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:[Base64 encodeFromString:kValueVersion] forHTTPHeaderField:kKeyVersion];
[request addValue:[Base64 encodeFromString:kValueDataTypeCmd] forHTTPHeaderField:kKeyDataType];
[request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyCmdName];
[request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyDeviceName];
[request addValue:[Base64 encodeFromString:@"xxdafadfadfa"] forHTTPHeaderField:kKeyDTLCookies];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}
Và sau đó, tôi bắt đầu Wireshark để bắt gói trên máy chủ (192.168.1.xxx), sử dụng "(tcp.flags .syn == 1) || (tcp.flags == 0x0010 & & tcp.seq == 1 & & tcp.ack == 1) "để lọc tcp lắc tay 3 chiều. Thật không may, tôi có thể thấy rung tay 3 chiều cho mỗi lần gọi "sendOneRequest". Có nghĩa là, NSURLConnection dường như không tái sử dụng các kết nối hiện có. Một số có thể chỉ ra những gì sai trong mã của tôi và làm thế nào để gửi nhiều yêu cầu thông qua một kết nối socket bởi NSURLConnection?
Tôi cũng đã cố gắng cách đồng bộ để gửi yêu cầu:
-(void)sendOneRequest {
NSURL *url = [NSURL URLWithString:@"http://192.168.1.100:1234"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:[Base64 encodeFromString:kValueVersion] forHTTPHeaderField:kKeyVersion];
[request addValue:[Base64 encodeFromString:kValueDataTypeCmd] forHTTPHeaderField:kKeyDataType];
[request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyCmdName];
[request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyDeviceName];
[request addValue:[Base64 encodeFromString:@"xxdafadfadfa"] forHTTPHeaderField:kKeyDTLCookies];
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
sleep(1);
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
sleep(1);
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
}
Và kết quả là như nhau.
======= CẬP NHẬT ============================
Cuối cùng, tôi đã tìm thấy lý do tại sao bài kiểm tra của tôi khác với Rob và Eric nói. Tóm lại, Rob và Eric là chính xác. Và NSURLConnection sử dụng "keep-alive" làm mặc định cho việc sử dụng HTTP/1.1 và tái sử dụng kết nối socket hiện có, nhưng chỉ cho một khung thời gian tương đối nhỏ.
Tuy nhiên, NSURLConnection có một số vấn đề về "mã chuyển mã chunked" (nghĩa là không có độ dài nội dung). Trong thử nghiệm của tôi, phía máy chủ gửi phản hồi mà không có dữ liệu về độ dài và nội dung đáp ứng, và phản hồi chunked của nó và NSURLConnection sẽ đóng kết nối, do đó rung tay 3 chiều xảy ra cho mỗi bài viết http.
Tôi đã thay đổi mã máy chủ của mình, đặt độ dài phản hồi là 0 và hành vi là chính xác.
nếu (! Kết nối) kết nối = [[NSURLKết nối kết nối] initWithRequest: yêu cầu ủy quyền: tự bắt đầuImmediately: NO]; [kết nối bắt đầu]; Cái này không hoạt động, nó cung cấp “EXC_BAD_ACCESS”. Tôi đã tìm kiếm các diễn đàn cho điều đó và không có câu trả lời. Có vẻ như 'bắt đầu' là cần thiết để sử dụng một cách khác. – slatvick
Đó là một sự kỳ quặc của phương pháp khởi tạo này mà bạn phải lên lịch kết nối trên một runloop trước khi bắt đầu nó. –