标签:
前两天从晚上买了个enc28j60模块,准备做个以太网的测试,回来的时候稍微有点小激动,为什么呢,据我的经验看来,一个人面对新的未知的事物,总会有点害怕,然后又有种跃跃欲试之感,或许我就是这样的,然后我把小小的模块拿出来,用杜邦线链接好之后找了段代码少了进去,那时候不知道咋连,他们说如果和路由器连接的话用直连网线,和pc机连接的话用交叉网线,什么呀,现在的pc机都可以判断设备的端口类型了额,自动转换直连和交叉,不需要费那么多功夫了。
话说一开始怎么都连接不上,ping不通,什么玩意儿啊,弄半天了没反应,一度陷入怀疑,怀疑这个模块是不是坏的,然后人家又说什么乱七八糟的原因,什么杜邦线导致时钟频率紊乱啊什么的,都是什么呀。后来我查了资料,原来需要设置pc机的ip子网掩码等信息,我就设置了下,然后断开无线网,Ping了下,卧槽,竟然通了,你能理解我当时的心情吗,当时脑海只闪现过三个字:我艹啦。。。
话不多说,虽然只是ping通,离项目完成还差的远,但是至少说明模块是好的吧,然后就开始看协议,tcp/ip,udp,lwip,uip,arp,。。。。。。无奈了,这都是啥玩意啊,我只用到udp啊,然后我把该删的全删了,然后看了udp的报文怎么组成的,然后。。。。。。。。。。。。。。。。。。。。。。。。
然后就可以发送数据了啊,也可以接受了啊,可是为毛线板子可以无限次接受,但是只能发送一次呢,当时有两个函数
void make_udp_reply_from_request(unsigned char *buf, char *data, unsigned int datalen, unsigned int port)
enc28j60PacketReceive(BUFFER_SIZE, buf);
第一个是发送报文的,第二个是接收报文的,我一直在解决为啥发送不出去的问题,然后想了想,不可能一个请求一个回复这种单工模式的,肯定可以无限发送的,因为我想到了我写的一个socket程序,以前上大一写的,对于服务器端,需要设置套接字啊,绑定端口啊,监听啊什么的,然后发送什么的,对于客户端,不需要绑定套接字,知道服务器的ip端口直接可以发送数据啊,我这么一想,对,有理,于是就根据udp协议开始组报文,什么20字节ip报头,8字节udp报头,什么什么的,还需要知道服务器的ip,mac,端口信息,然后就可以无限发送了,到此这个模块udp功能算是搞懂了,把发送的代码贴上,让大家看下,
// you can send a max of 220 bytes of data //srcport 我的端口,dstport 对方端口 void make_udp_send(unsigned int srcport, unsigned int dstport, unsigned char* data, unsigned char datalen) { unsigned char i = 0; unsigned int ck; //make_eth(buf); // if((stateSend==0)||(stateStop==0))return; //if(stateSend==0)return; while (i < 6) { sendbuf[ETH_DST_MAC + i] = dstmac[i]; sendbuf[ETH_SRC_MAC + i] = mymac[i]; i++; } i=0; if (datalen > 220) { datalen = 220; } // total length field in the IP header must be set: sendbuf[IP_TOTLEN_H_P] = 0; sendbuf[IP_TOTLEN_L_P] = IP_HEADER_LEN + UDP_HEADER_LEN + datalen; //make_dstip(buf); sendbuf[12] = 0x08; sendbuf[13] = 0x00; sendbuf[14] = 0x45; sendbuf[15] = 0x00; sendbuf[20] = 0x00; sendbuf[21] = 0x00; sendbuf[22] = 0x40; sendbuf[23] = 0x11; i = 0; while (i < 4) { sendbuf[IP_DST_P + i] = dstip[i]; sendbuf[IP_SRC_P + i] = myip[i]; i++; } i = 0; fill_ip_hdr_checksum(sendbuf); sendbuf[UDP_SRC_PORT_H_P] = srcport >> 8; sendbuf[UDP_SRC_PORT_L_P] = srcport & 0xff; sendbuf[UDP_DST_PORT_H_P] = dstport >> 8; sendbuf[UDP_DST_PORT_L_P] = dstport & 0xff; // source port does not matter and is what the sender used. // calculte the udp length: sendbuf[UDP_LEN_H_P] = 0; sendbuf[UDP_LEN_L_P] = UDP_HEADER_LEN + datalen; // zero the checksum sendbuf[UDP_CHECKSUM_H_P] = 0; sendbuf[UDP_CHECKSUM_L_P] = 0; // copy the data: while (i < datalen) { sendbuf[UDP_DATA_P + i] = data[i]; i++; } ck = checksum(&sendbuf[IP_SRC_P], 16 + datalen, 1); sendbuf[UDP_CHECKSUM_H_P] = ck >> 8; sendbuf[UDP_CHECKSUM_L_P] = ck & 0xff; enc28j60PacketSend(UDP_HEADER_LEN + IP_HEADER_LEN + ETH_HEADER_LEN + datalen, sendbuf); }
知识是需要共享的,希望中国人不要藏私,这样中国才能发展起来,国家才能富强!
标签:
原文地址:http://my.oschina.net/u/2252538/blog/490758