remote_ip.addr>>8 )&0xff ; //iaddr3 lwipdev.remoteip[ 2 ] = ( tpcb->remote_ip.addr>>16 )&0xff ; //iaddr2 lwipdev.remoteip[ 3 ] = ( tpcb->remote_ip.addr>>24 )&0xff ; //iaddr1 tcp_recved( tpcb, p->tot_len ) ; //用于获取接收数据 pbuf_free( p ) ; //释放内存 ret_err = err_ok ; } } //服务器关闭了 else { tcp_recved( tpcb, p->tot_len ); //用于获取接收数据 es->p= null ; pbuf_free( p ) ; //释放内存 ret_err = err_ok ; } return ret_err ;}// tcp_err函数的回调函数void tcp_server_error( void *arg, err_t err ){ lwip_unused_arg( err ) ; printf( tcp error:%x\\r\\n, ( u32 )arg ) ; //释放内存 if( arg!=null ) mem_free( arg ) ;}//发送数据void tcp_server_senddata( struct tcp_pcb *tpcb, struct tcp_server_struct *es ){ struct pbuf *ptr ; u16 plen ; err_t wr_err = err_ok ; while( ( wr_err==err_ok )&&( es->p )&&( es->p->lenp ; wr_err = tcp_write( tpcb, ptr->payload, ptr->len, 1 ) ; if( wr_err==err_ok ) { plen = ptr->len ; es->p = ptr->next ; //指向下一个pbuf //pbuf的ref加一 if( es->p ) pbuf_ref( es->p ) ; pbuf_free( ptr ) ; tcp_recved( tpcb, plen ) ; //更新tcp窗口大小 } else if( wr_err==err_mem ) es->p = ptr ; }}// tcp_poll的回调函数const u8 *tcp_server_sendbuf = stm32f103 tcp server send data\\r\\n ; //tcp服务器发送数据内容err_t tcp_server_poll( void *arg, struct tcp_pcb *tpcb ){ err_t ret_err; struct tcp_server_struct *es ; es = ( struct tcp_server_struct* )arg ; if( es!=null ) { //判断是否有数据要发送 if( tcp_server_flag&( 1p, ( char* )tcp_server_sendbuf, strlen( ( char* )tcp_server_sendbuf ) ) ; tcp_server_senddata( tpcb, es ) ; //轮询的时候发送要发送的数据 tcp_server_flag &= ~( 1
p ) ; //释放内存 } //关闭操作 else if( es->state==es_tcpserver_closing ) tcp_server_connection_close( tpcb, es ) ; //关闭连接 ret_err = err_ok ; } else { tcp_abort( tpcb ) ; //终止连接,删除pcb控制块 ret_err = err_abrt ; } return ret_err ;}// tcp_sent的回调函数(远端收到ack信号后发送数据)err_t tcp_server_sent( void *arg, struct tcp_pcb *tpcb, u16_t len ){ struct tcp_server_struct *es ; lwip_unused_arg( len ) ; es = ( struct tcp_server_struct * )arg ; if( es->p ) tcp_server_senddata( tpcb, es ) ; //发送数据 return err_ok ;}//强制删除主动断开时的time waitextern void tcp_pcb_purge( struct tcp_pcb *pcb ) ; //在 tcp.c里面extern struct tcp_pcb *tcp_active_pcbs ; //在 tcp.c里面extern struct tcp_pcb *tcp_tw_pcbs ; //在 tcp.c里面void tcp_server_remove_timewait(){ struct tcp_pcb *pcb, *pcb2 ; while( tcp_active_pcbs!=null ) { lwip_periodic_handle() ; //继续轮询 lwip_pkt_handle() ; delay_ms( 10 ) ; //等待tcp_active_pcbs为空 } pcb = tcp_tw_pcbs ; //如果有等待状态的pcbs while( pcb!=null ) { tcp_pcb_purge( pcb ) ; tcp_tw_pcbs = pcb->next ; pcb2 = pcb ; pcb = pcb->next ; memp_free( memp_tcp_pcb, pcb2 ) ; }}// tcp_accept的回调函数err_t tcp_server_accept( void *arg, struct tcp_pcb *newpcb, err_t err ){ err_t ret_err ; struct tcp_server_struct *es ; lwip_unused_arg( arg ) ; lwip_unused_arg( err ) ; tcp_setprio( newpcb, tcp_prio_min ) ; //设置新创建的pcb优先级 es = ( struct tcp_server_struct* )mem_malloc( sizeof( struct tcp_server_struct ) ) ; //分配内存 //内存分配成功 if( es!=null ) { es->state = es_tcpserver_accepted ; //接收连接 es->pcb = newpcb ; es->p = null ; tcp_arg( newpcb, es ) ; tcp_recv( newpcb, tcp_server_recv ) ; //初始化tcp_recv的回调函数 tcp_err( newpcb, tcp_server_error ) ; //初始化tcp_err回调函数 tcp_poll( newpcb, tcp_server_poll, 1 ) ; //初始化tcp_poll回调函数 tcp_sent( newpcb, tcp_server_sent ) ; //初始化发送回调函数 tcp_server_flag |= 1remote_ip.addr>>8 )&0xff ; //iaddr3 lwipdev.remoteip[ 2 ] = ( newpcb->remote_ip.addr>>16 )&0xff ; //iaddr2 lwipdev.remoteip[ 3 ] = ( newpcb->remote_ip.addr>>24 )&0xff ; //iaddr1 ret_err = err_ok ; } else ret_err = err_mem ; return ret_err ;}// tcp server 测试void tcp_server_test(){ err_t err ; struct tcp_pcb *tcppcbnew ; //定义一个tcp服务器控制块 struct tcp_pcb *tcppcbconn ; //定义一个tcp服务器控制块 u8 *tbuf ; u8 res=0 ; u8 connflag=0 ; //连接标记 tbuf = mymalloc( sramin, 200 ) ; //申请内存 //内存申请失败了,直接退出 if( tbuf==null ) return ; sprintf( ( char* )tbuf, server ip:%d.%d.%d.%d, lwipdev.ip[0], lwipdev.ip[1], lwipdev.ip[2], lwipdev.ip[3] ) ; lcd_showstring( 30, 130, tbuf ) ; //服务器ip sprintf( ( char* )tbuf, server port:%d, tcp_server_port ) ; lcd_showstring( 30, 150, tbuf ) ; //服务器端口号 tcppcbnew = tcp_new() ; //创建一个新的pcb //创建成功 if( tcppcbnew ) { err = tcp_bind( tcppcbnew, ip_addr_any, tcp_server_port ) ; //将本地ip与指定端口号绑定 //绑定完成 if( err==err_ok ) { tcppcbconn = tcp_listen( tcppcbnew ) ; //设置tcppcb进入监听状态 tcp_accept( tcppcbconn, tcp_server_accept ) ; //初始化tcp_accept的回调函数 } else res = 1 ; } else res = 1 ; while( res==0 ) { //收到数据 if( tcp_server_flag&1<<6 ) { tcp_server_flag |= 1<<7 ; //标记要发送数据 lcd_showstring( 30, 210, tcp_server_recvbuf ) ; //显示接收到的数据 tcp_server_flag &= ~( 1<<6 ) ; //标记数据已经被处理了 } //是否连接上 if( tcp_server_flag&1<<5 ) { if( connflag==0 ) { sprintf( ( char* )tbuf, client ip:%d.%d.%d.%d, lwipdev.remoteip[0], lwipdev.remoteip[1], lwipdev.remoteip[2], lwipdev.remoteip[3] ) ; lcd_showstring( 30, 170, tbuf ) ; //客户端ip lcd_showstring( 30, 190, receive data: ) ; //提示消息 connflag = 1 ; //标记连接了 } } else if( connflag ) connflag = 0 ; //标记连接断开了 lwip_periodic_handle() ; lwip_pkt_handle() ; delay_ms( 2 ) ; } tcp_server_connection_close( tcppcbnew, 0 ) ; //关闭tcp server连接 tcp_server_connection_close( tcppcbconn, 0 ) ; //关闭tcp server连接 tcp_server_remove_timewait() ; memset( tcppcbnew, 0, sizeof( struct tcp_pcb ) ) ; memset( tcppcbconn, 0, sizeof( struct tcp_pcb ) ) ; myfree( sramin, tbuf ) ;}27.1.2 tcp_server.h代码编写#ifndef _tcp_server_demo_h_#define _tcp_server_demo_h_#include sys.h#include lwip/tcp.h#include lwip/pbuf.h#define tcp_server_rx_bufsize 2000 //定义tcp server最大接收数据长度#define tcp_server_port 8088 //定义tcp server的端口//tcp服务器连接状态enum tcp_server_states{ es_tcpserver_none = 0, //没有连接 es_tcpserver_accepted, //有客户端连接上了 es_tcpserver_closing, //即将关闭连接};//lwip回调函数使用的结构体struct tcp_server_struct{ u8 state; //当前连接状 struct tcp_pcb *pcb; //指向当前的pcb struct pbuf *p; //指向接收/或传输的pbuf}; void tcp_server_test( void ) ; //tcp server测试函数#endif27.1.3 主函数代码编写#include sys.h#include delay.h#include usart1.h#include tim.h#include lcd.h#include malloc.h#include dm9000.h#include lwip/netif.h#include comm.h#include lwipopts.h#include tcp_server.hint main(){ u8 buf[ 30 ]; stm32_clock_init( 9 ) ; //系统时钟设置 systick_init( 72 ) ; //延时初始化 usart1_init( 72, 115200 ) ; //串口初始化为115200 lcd_init() ; //初始化lcd tim3_init( 1000, 719 ) ; //定时器3频率为100hz my_mem_init( sramin ) ; //初始化内部内存池 while( lwip_comm_init() ) ; //lwip初始化 //等待dhcp获取成功/超时溢出 while( ( lwipdev.dhcpstatus!=2 )&&( lwipdev.dhcpstatus!=0xff ) ) { lwip_periodic_handle() ; //lwip内核需要定时处理的函数 lwip_pkt_handle() ; } point_color=red; lcd_showstring( 30, 110, lwip init successed ) ; //打印动态ip地址 if( lwipdev.dhcpstatus==2 ) sprintf( ( char* )buf, dhcp ip:%d.%d.%d.%d, lwipdev.ip[0], lwipdev.ip[1], lwipdev.ip[2], lwipdev.ip[3] ) ; //打印静态ip地址 else sprintf( ( char* )buf, static ip:%d.%d.%d.%d, lwipdev.ip[0], lwipdev.ip[1], lwipdev.ip[2], lwipdev.ip[3] ) ; lcd_showstring( 30, 130, buf ) ; //得到网速 if( ( dm9000_get_speedandduplex()&0x02 )==0x02 ) lcd_showstring( 30, 150, ethernet speed:10m ) ; else lcd_showstring( 30, 150, ethernet speed:100m ) ; while( 1 ) { tcp_server_test() ; //tcp服务器测试 lwip_periodic_handle() ; lwip_pkt_handle() ; delay_ms( 2 ) ; }}27.2 实验结果
聚酯装置DCS系统的硬件配置及在接地和电源方面的问题分析
将彩电延时电路应用于重合闸,Delay switch
可充电触屏遥控模块电路设计
LDR6020Type-C一拖二同时快充超低成本方案
全球首位3D版AI合成主播“新小微”正式亮相
有线网络通信实验4之TCP服务器
关于KUKA机器人的内部结构介绍
压敏电阻五种过热保护技术分析
中国移动多维度推进5G应用创新发展,推动产业成熟和生态构建
直线模组有哪些配件组成的?
开年旗舰华为荣耀V9发布,盲约已经开启,看点有很多
万华化学多款产品获得ISCC PLUS认证
SymCool IQ智能电源模块增加针对双向操作优化的集成智能驱动器
特斯拉宣布将在欧洲建设第二座超级工厂
公有云对数据安全的保障措施都有哪些
基于ARM Cortex A9核心Rayeager PX2开发板电路图
数字视频矩阵特点
物联网系统安全得靠什么手段来保证
港大带头研发OLED材料 为香港创出迈进世界水平的技术
IMAGE3图像测量仪应用之汽车刹车片尺寸测量