NetBIOS协议是一种在局域网上的程序可以使用的应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能,几乎所有的局域网都是在NetBIOS协议的基础上工作的� NetBIOS协议,简单来说就是通过访问设备名称就可以实现对IP地址的访问。在Windows操作系统中,默认情况下在安装TCP/IP协议后会自动安装NetBIOS协议。NetBIOS的报文类型较多、结构复杂,在不同的网络环境和不同的用途中会使用不同的报文,可用端口进行区分, NetBIOS数据报报文使用UDP 138端口,NetBIOS会话报文使用TCP 139端口。本节主要通过NetBIOS协议实现把IP地址解析为对应的一个名字,就比�180.97.33.107是百度服务器的IP地址,对应的名字是“www.baidu.com”。这样我们就不用记住很多的IP地址,通过一个简单的名字就可搜索到相应的信息� 本例程首先通过DHCP获取一个动态IP地址分配给W5500,然后通过NetBIOS协议来解析W5500这个名字和IP地址对应,然后添加HTTP服务器功能,在网页中输入W5500就可以进入相应的网页信息,在windows下ping W5500也可以得到对应的IP地址信息。程序的Main很简单,主要是网络初始化和芯片的初始化� 由于本程序通过DHCP获取动态IP以后,再通过NetBIOS实现名字解析的,所以要在w5500_conf.c文件下定义ip_from为IP_FROM_DHCP。NetBIOS的处理主要在NetBIOS.c中。在do_netbios函数中对UDP广播查询做了解析,并且回应。这就完成了b节点的NetBIOS名称服务。在do_netbios中一个Socket在指定的 端口一直侦听,如果收到数据包就判断格式,看是不是NetBIOS查询包。如果是,调用netbios_name_decoding函数解包。之后按照NetBIOS格式组包回复�
NetBIOS实现过程示意图如下:while(1) /*循环执行的函�*/ { do_dhcp(); /*从DHCP服务器获取IP地址*/ if(dhcp_ok==1) /*获取IP地址之后*/ { do_https(); /*打开HTTP Server*/ do_netbios(); /*NetBios测试程序*/ } } void do_netbios(void) { unsigned char state; unsigned int len,i; state = getSn_SR(NETBIOS_SOCK); switch(state) { case SOCK_UDP: if((len=getSn_RX_RSR(NETBIOS_SOCK))>0) { unsigned char rem_ip_addr[4]; uint16 rem_udp_port; char netbios_name[NETBIOS_NAME_LEN+1]; NETBIOS_HDR* netbios_hdr; NETBIOS_NAME_HDR* netbios_name_hdr; if (((netbios_hdr->flags & ntohs(NETB_HFLAG_OPCODE)) == ntohs(NETB_HFLAG_OPCODE_NAME_QUERY)) && ((netbios_hdr->flags & ntohs(NETB_HFLAG_RESPONSE)) == 0) && (netbios_hdr->questions == ntohs(1))) { printf("netbios name query question\r\n"); netbios_name_decoding( (char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name)); printf("name is %s\r\n",netbios_name); if (strcmp(netbios_name, NETBIOS_W5500_NAME) == 0) { uint8 ip_addr[4]; NETBIOS_RESP *resp = (NETBIOS_RESP*)netbios_tx_buf; printf("name is matched!\r\n"); /* 处理NetBIOS响应包的header*/ resp->resp_hdr.trans_id = netbios_hdr->trans_id; resp->resp_hdr.flags = htons(NETB_HFLAG_RESPONSE |NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE |NETB_HFLAG_RECURS_DESIRED); resp->resp_hdr.questions = 0; resp->resp_hdr.answerRRs = htons(1); resp->resp_hdr.authorityRRs = 0; resp->resp_hdr.additionalRRs = 0; memcpy( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname)); resp->resp_name.nametype = netbios_name_hdr->nametype; resp->resp_name.type = netbios_name_hdr->type; resp->resp_name.cls = netbios_name_hdr->cls; resp->resp_name.ttl = htonl(NETBIOS_NAME_TTL); resp->resp_name.datalen = htons(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr)); resp->resp_name.flags = htons(NETB_NFLAG_NODETYPE_BNODE); getSIPR(ip_addr); memcpy(resp->resp_name.addr,ip_addr,4); sendto(NETBIOS_SOCK, (unsigned char*)resp, sizeof(NETBIOS_RESP), rem_ip_addr, rem_udp_port); printf("send response\r\n"); } else printf("name is not matched!\r\n"); } } break; case SOCK_CLOSED: close(NETBIOS_SOCK); socket(NETBIOS_SOCK,Sn_MR_UDP,NETBIOS_PORT,0); break; default: break; } }NetBIOS的具体测试步骤如�