目前共有7篇帖子。
uip中的UDP功能用法
1樓 巨大八爪鱼 2017-5-26 16:57
【初始化代碼】
void myapp_init(uip_ipaddr_t *ipaddr)
{
    // UDP埠監聽
    uip_ipaddr(ipaddr, 192, 168, 1, 2); // 客戶端IP
    uconn = uip_udp_new(ipaddr, HTONS(82)); // 客戶端埠號
    uip_udp_bind(uconn, HTONS(12345)); // 本機埠號
}
2樓 巨大八爪鱼 2017-5-26 17:00
【UDP回調函數】
void uip_udp_appcall(void)
{
    char buf[20];

    // 定期檢測事件
    if (uip_poll())
    {
        if (send_udp_packet) // 如果該變數為1,則無條件發送一個UDP數據包
        {
            strcpy_P(uip_appdata, PSTR("This is a string."));
            uip_udp_send(strlen(uip_appdata));
            send_udp_packet = 0;
        }
    }
   
    // 若收到了UDP數據包
    if (uip_newdata())
    {
        // 提取數據包前19位元組內容到buf中
        if (uip_len >= sizeof(buf))
            uip_len = sizeof(buf) - 1;
        strncpy(buf, uip_appdata, uip_len);
        buf[uip_len] = '\0';

        // 組裝生成新數據包
        strcpy_P(uip_appdata, PSTR("New data arrived: "));
        strcat(uip_appdata, buf);

        // 發送回應
        uip_udp_send(strlen(uip_appdata));
        // 由於當ARP緩存表中沒有客戶端MAC地址時,uip會用ARP請求數據包把uip_appdata中的內容給覆蓋掉
        // 只發送ARP請求而不發送數據包內容
        // 因此第一次發送的數據包很可能會丟失
    }
}
3樓 巨大八爪鱼 2017-5-26 17:02
【PC端測試用的Java程序】
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Sender {
    public static void main(String[] args) {
        try {
            DatagramSocket ds = new DatagramSocket(82); // 本機埠
            byte[] data = "Hello,_World!_This_is_a_long_string.".getBytes();
            DatagramPacket dp = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.1.50"), 12345); // 伺服器IP位址和埠號
            System.out.println("Begin...");
            ds.send(dp);
            System.out.println("Sent!");
           
            data = new byte[100];
            dp = new DatagramPacket(data, data.length);
            ds.receive(dp);
           
            System.out.println("Recved: " + new String(data, 0, dp.getLength()));
           
            ds.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
【運行結果】
Begin...
Sent!
Recved: New data arrived: Hello,_World!_This_
4樓 巨大八爪鱼 2017-5-26 17:44
【UDP監聽任意埠的方法】
uip_ipaddr(ipaddr, 0, 0, 0, 0);
uconn = uip_udp_new(ipaddr, 0); // 可監聽任意客戶端任意埠
uip_udp_bind(uconn, HTONS(12345)); // 但必須指定本機埠號
5樓 巨大八爪鱼 2017-5-26 17:44
#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])

void uip_udp_appcall(void)
{
    char buf[20];

    // 定期檢測事件
    // 現在沒有客戶端IP位址和埠號了, 所以下面這段代碼不能正常工作
    /*
    if (uip_poll())
    {
        if (send_udp_packet) // 如果該變數為1,則無條件發送一個UDP數據包
        {
            strcpy_P(uip_appdata, PSTR("This is a string."));
            uip_udp_send(strlen(uip_appdata));
            send_udp_packet = 0;
        }
    }
    */
    
    // 若收到了UDP數據包
    if (uip_newdata())
    {
        // 提取數據包前19位元組內容到buf中
        if (uip_len >= sizeof(buf))
            uip_len = sizeof(buf) - 1;
        strncpy(buf, uip_appdata, uip_len);
        buf[uip_len] = '\0';

        // 根據客戶端的地址修改當前UDP連接, 否則回應數據包將無法發送出去
        // 修改後該連接(uconn)將只能接收該客戶端的數據包
        // 這個問題只能通過修改uip.c中標籤udp_send:的代碼解決
        uip_ipaddr_copy(uip_udp_conn->ripaddr, UDPBUF->srcipaddr); // 獲取客戶端IP位址
        uip_udp_conn->rport = UDPBUF->srcport; // 獲取客戶端埠號

        // 組裝生成新數據包
        strcpy_P(uip_appdata, PSTR("New data arrived: "));
        strcat(uip_appdata, buf);
        // 附上客戶端的IP位址和埠號信息
        sprintf_P(buf, PSTR("\nIP: %d.%d.%d.%d"), uip_udp_conn->ripaddr[0] & 0xff, uip_udp_conn->ripaddr[0] >> 8, uip_udp_conn->ripaddr[1] & 0xff, uip_udp_conn->ripaddr[1] >> 8);
        strcat(uip_appdata, buf);
        sprintf_P(buf, PSTR("\nPort: %d"), ntohs(uip_udp_conn->rport));
        strcat(uip_appdata, buf);

        // 發送回應
        uip_udp_send(strlen(uip_appdata));
        // 由於當ARP緩存表中沒有客戶端MAC地址時,uip會用ARP請求數據包把uip_appdata中的內容給覆蓋掉
        // 只發送ARP請求而不發送數據包內容
        // 因此第一次發送的數據包很可能會丟失
    }
}
6樓 巨大八爪鱼 2017-5-26 17:45
【運行結果】
Begin...
Sent!
Recved: New data arrived: Hello,_World!_This_
IP: 192.168.1.2
Port: 82
7樓 巨大八爪鱼 2017-5-26 17:46
如果不修改uip的原始碼,則只能實現一次性監聽任意客戶端。監聽成功後將只能從該客戶端收發數據。

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。