2012-04-22 81 views
6

Tôi đang sử dụng FreeRTOS + LwIP để phát triển thiết bị gọi y tá bên giường dựa trên Ethernet. Sau khi đọc một số ví dụ và tài liệu, tôi muốn sử dụng API mạng của LwIP để gửi và nhận dữ liệu theo TCP, vì tôi không quen với API kiểu BSD và API thô có thể khó khăn.LwIP - netconn API - Gửi gói TCP trong khi quá trình bị chặn?

Tôi biết netconn_accept() chức năng sẽ chặn quá trình này cho đến khi một yêu cầu kết nối từ một máy chủ từ xa đến, và netconn_recv() chức năng cũng sẽ chặn quá trình này trong khi chờ đợi dữ liệu đến ... cả hai chức năng sẽ khối sự tuy nhiên, nó là tốt cho một máy chủ nhận dữ liệu, thiết bị của tôi cũng cần phải hoạt động như một khách hàng cần kích hoạt một 'cuộc gọi' đến trung tâm y tá khi bệnh nhân nhấn một nút. Vậy làm thế nào nó có thể khởi tạo để gửi một gói TCP trong khi nó cũng đang chờ kết nối (chặn quá trình) từ máy chủ từ xa?

Tôi cần gửi TCP vì tôi phải sử dụng SIP (Giao thức khởi tạo phiên) để bắt đầu cuộc gọi, nó đáng tin cậy vì đây là thiết bị y tế. Thank you very much


@ Kyle Heironimus, @werewindle tôi thêm bạn vào câu hỏi của tôi bởi vì tôi biết bạn có kinh nghiệm về LwIP, hy vọng rằng sẽ không làm cho bạn bất tiện và hy vọng rằng bạn có thể giúp đỡ, cảm ơn bạn.

+0

Vì tôi đang sử dụng FreeRTOS, hôm nay tôi đã cố gắng sử dụng hai luồng, một chủ đề đang chờ kết nối, một máy chủ khác làm máy khách để mở kết nối TCP khi cần. Các thread máy chủ đang làm tốt, nhưng ở phía khách hàng, nó luôn luôn trở về lỗi khi tôi gọi 'netconn_connect()' ... Tôi đã cố gắng sử dụng cùng một cổng khác nhau cho máy chủ và máy khách, nhưng vẫn thất bại – eepty

Trả lời

6

Bạn không thể gửi dữ liệu đến máy chủ từ xa trước khi nó bắt đầu kết nối. Điều đó không có ý nghĩa gì cả. Câu hỏi của tôi là: bạn có muốn thiết bị của mình kết nối với máy chủ từ xa không hoặc bạn có muốn máy chủ từ xa bắt đầu kết nối với thiết bị của mình không?

Ngay bây giờ bạn đang sử dụng netconn_accept trong thiết bị - điều đó có nghĩa là bạn đang đợi máy chủ từ xa bắt đầu kết nối với thiết bị của mình trước khi thiết bị có thể báo hiệu máy chủ từ xa. Đây là hành vi hoàn toàn mong đợi đối với mã bạn đã viết nhưng dường như bạn lo lắng về điều này. Đây không phải là ý định của bạn? Nếu không, tại sao bạn mã nó theo cách đó? Cách khác là để thiết bị của bạn khởi tạo kết nối với máy chủ từ xa. Có một ví dụ về việc sử dụng netconns here. Tất nhiên, điều này cũng liên quan đến những thay đổi đối với thiết bị khác trong hệ thống của bạn.

Vì vậy, đạo đức của câu chuyện đó là bạn không thể gửi bất kỳ dữ liệu nào khi không có kết nối và bạn đang chờ kết nối trước khi gửi dữ liệu. Bạn không muốn đợi kết nối, vì vậy bạn phải thay đổi phần mềm của mình để bắt đầu kết nối thay vì đợi phía bên kia bắt đầu kết nối.

Một vấn đề khác mà bạn có thể gặp phải là bạn muốn có thể gửi và nhận dữ liệu trên cùng một kết nối cùng một lúc. Hầu hết các ví dụ tôi thấy cho lwip liên quan đến việc chặn các cuộc gọi chờ dữ liệu, sau đó phản ứng lại dữ liệu đó bằng cách truyền lại một số thứ. Đôi khi bạn muốn truyền lại thứ gì đó mà không nhận được thứ gì đó trước. Tôi cũng có thể giúp với điều đó.

Đây là những gì đã hiệu quả đối với tôi khi tôi tạo kết nối netconn đang nghe.

Trước tiên, bạn phải kích hoạt bằng cách thiết lập timeout:

#define LWIP_SO_RCVTIMEO 1

Sau đó, bạn phải thiết lập netconn của bạn tương tự như này:

pxTCPListener = netconn_new (NETCONN_TCP);

netconn_bind (pxTCPListener, NULL, 23);

netconn_listen (pxTCPListener);

pxNewConnection = netconn_accept (pxTCPListener); // Khối này cho đến khi kết nối được chấp nhận

// Đây là dòng quan trọng!

pxNewConnection-> recv_timeout = 10; // lưu ý Đây là millseconds - lwip làm việc trong ms

// Đây vòng cho đến khi kết nối được đóng

while (ERR_IS_FATAL (pxNewConnection-> err)!) {// lỗi Fatal bao gồm các kết nối bị đóng cửa, thiết lập lại , hủy bỏ, vv

// gọi netconn_recv này bây giờ sẽ chờ 10ms đối với bất kỳ dữ liệu mới, sau đó trở về

if ((pxRxBuffer = netconn_recv (pxNewConnection))! = NULL) {

// Xử lý nhận d dữ liệu

}

// Ở đây, làm bất cứ truyền bạn muốn

} // Kết thúc vòng lặp while từ trên

Đó là mã sẽ cho phép bạn làm truyền và nhận tại đồng thời không lo lắng về việc chặn.

+0

Cảm ơn Stephen, thiết bị gọi y tá sẽ hoạt động như một máy chủ, chờ kết nối, – eepty

+0

Vâng ... tại sao vậy? Có vẻ như thiết bị cuộc gọi sẽ bắt đầu kết nối với máy chủ vì hành động kích hoạt tất cả điều này là ai đó đang nhấn nút trên đó thay vì đợi một thứ gì đó kết nối với máy chủ để có thể cho biết nút đó đã được nhấn. –

+0

Cảm ơn bạn rất nhiều cho bạn câu trả lời chi tiết Stephen. Thiết bị này giống như một chiếc điện thoại, nó chờ kết nối bình thường, hoạt động như một máy chủ, nhưng nếu một người nhấn một nút trên nó, nó sẽ bắt đầu một kết nối, hoạt động như một máy khách. Hai tình huống này sẽ không tồn tại cùng một lúc, và cả hai tình huống liên quan đến việc nhận và truyền tải. Gần đây tôi đã thành công để thực hiện hai nhiệm vụ này một cách riêng biệt .. sau khi đọc dài ... Tôi đã tách chúng thành hai tác vụ khác nhau trong FreeRTOS, cho phép một tác vụ sẽ chặn một tác vụ khác. Tôi đã thử nghiệm từng nhiệm vụ riêng biệt nhưng không thử nghiệm chúng chạy cùng nhau ... Tôi mới tham gia RTOS nhưng tôi sẽ thử – eepty