|
【初始化代码】 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)); // 本机端口号 }
|
|
【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请求而不发送数据包内容 // 因此第一次发送的数据包很可能会丢失 } }
|
|
【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_
|
|
【UDP监听任意端口的方法】 uip_ipaddr(ipaddr, 0, 0, 0, 0); uconn = uip_udp_new(ipaddr, 0); // 可监听任意客户端任意端口 uip_udp_bind(uconn, HTONS(12345)); // 但必须指定本机端口号
|
|
#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请求而不发送数据包内容 // 因此第一次发送的数据包很可能会丢失 } }
|
|
【运行结果】 Begin... Sent! Recved: New data arrived: Hello,_World!_This_ IP: 192.168.1.2 Port: 82
|
|
如果不修改uip的源代码,则只能实现一次性监听任意客户端。监听成功后将只能从该客户端收发数据。
|