2010-07-25 26 views
5

Tôi gặp sự cố lạ khi gửi gói UDP từ iPhone qua 3G. Hầu như mỗi lần ứng dụng của tôi bắt đầu sau một khoảng thời gian không hoạt động mạng dài hơn (ví dụ sau khi điện thoại đến từ chế độ ngủ hoặc nó chỉ nhận được kết nối 3G), ứng dụng của tôi không thể gửi bất kỳ gói UDP nào. Tôi nhận được trạng thái lỗi kCFSocketError từ CFSocketSendData. Logic ứng dụng sau đó cố gắng gửi gói định kỳ theo định kỳ cứ sau năm giây, nhưng cho dù tôi để cho nó chạy như thế nào nó vẫn bị lỗi. Tuy nhiên, khi tôi chuyển ứng dụng sang nền và mở, ví dụ, một trang web trong Safari (trong khi ứng dụng vẫn không hoạt động trên nền), ứng dụng đột nhiên bắt đầu hoạt động. Về cơ bản, nó có vẻ như các hoạt động mạng khác (từ Safari, Maps, vv) "khởi động mạng cho thực". Tôi có cần phải làm bất cứ điều gì đặc biệt về khởi tạo mạng không?Gửi gói UDP trên iPhone không thành công qua kết nối 3G mới, nhưng hoạt động khác

Đây là một đoạn mã đơn giản của các mã tôi đang sử dụng để gửi các gói tin UDP:

CFSocketRef cfSocket = CFSocketCreate(NULL, 0, SOCK_DGRAM, IPPROTO_UDP, kCFSocketNoCallBack, NULL, NULL); 
if (!cfSocket) 
{ 
    // snip: some error handling 
} 

struct sockaddr_in addr; 
// snip: init addr 

CFDataRef cfAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr)); 

CFSocketError sendPacketResult = CFSocketSendData(cfSocket, cfAddr, cfPacketData, 0.0); 
if (sendPacketResult != kCFSocketSuccess) 
{ 
    // try again in 5 seconds 
} 

Tất cả đều hoạt động tốt mà không cần bất kỳ vấn đề thông qua Wi-Fi.

Để công bằng, tôi nghĩ tôi đã nhìn thấy đôi khi (nhưng rất thường xuyên) hành vi tương tự trong các ứng dụng iPhone chuẩn (Safari, Maps, ...). Đôi khi họ từ chối kết nối (thậm chí nghĩ rằng tôi thấy biểu tượng 3G) và tôi cần phải đóng và mở lại chúng. Nhưng nó rất hiếm.

Chỉnh sửa: Có thể có câu hỏi liên quan: On iPhone, what does EPERM (errno == 1) mean in reponse to send() of UDP data?.

+0

Bao giờ làm việc này? –

Trả lời

4

Giao diện mạng TCP/IP 3G có thể bị phá hủy bởi IOS theo niềm vui của hệ điều hành, thường là vì lý do tiết kiệm điện nếu không có lưu lượng truy cập nào vượt qua nó. Khi sử dụng ổ cắm BSD (ví dụ, đối với UDP, vì không có khung mạng Apple UDP), không có cuộc gọi hệ điều hành được xuất bản nào để đảm bảo giao diện mạng 3G đang hoạt động. Nhưng nội bộ trong lớp CFSocketStream của Apple có tồn tại các cuộc gọi riêng của Apple để đánh thức giao diện.

Vì vậy, giải pháp dường như là mở CFSocketStream đến một nơi nào đó. Điều đó sẽ đánh thức giao diện trong một khoảng thời gian. Miễn là bạn gửi dữ liệu qua CFSocketStream sau một phút hoặc lâu hơn, kết nối và giao diện mạng sẽ vẫn hoạt động.

Đây không phải là tất cả những gì hấp dẫn, vì nó chỉ hoạt động theo hiệu ứng phụ. Nhưng nó có vẻ là giải pháp duy nhất vào thời điểm này.

Các vấn đề liên quan