zoukankan      html  css  js  c++  java
  • LWIP_STM32_ENC28J60_NETCONN_TCP_CLIENT(4)

        既然udp说完了,那接下来自然就是TCP通讯了,今天说说TCP客户端通讯,也就是单片机作为客户端,主机PC作为服务器

        相比于udp而言,tcp增加了一个连接服务器的流程,首先还是创建tcp_client任务

        

    //创建TCP客户端线程
    //返回值:0 TCP客户端创建成功
    //        其他 TCP客户端创建失败
    INT8U tcp_client_init(void)
    {
        INT8U res;
        OS_CPU_SR cpu_sr;
        
        OS_ENTER_CRITICAL();    //关中断
        res = OSTaskCreate(tcp_client_thread,(void*)0,(OS_STK*)&TCPCLIENT_TASK_STK[TCPCLIENT_STK_SIZE-1],TCPCLIENT_PRIO); //创建TCP客户端线程
        OS_EXIT_CRITICAL();        //开中断
        
        return res;
    }

    任务的执行流程如下

    //tcp客户端任务函数
    static void tcp_client_thread(void *arg)
    {
        OS_CPU_SR cpu_sr;
        u32 data_len = 0;
        struct pbuf *q;
        err_t err,recv_err;
        static ip_addr_t server_ipaddr,loca_ipaddr;
        static u16_t          server_port,loca_port;
    
        LWIP_UNUSED_ARG(arg);
        server_port = REMOTE_PORT;
        IP4_ADDR(&server_ipaddr, 192,168, 1,105);
        
        while(dhcpstatus != 2)//等待dhcp成功
        {
            OSTimeDly(10);
            //printf("wait dhcp
    ");
        }
        
        while (1) 
        {
            tcp_clientconn = netconn_new(NETCONN_TCP);  //创建一个TCP链接
            err = netconn_connect(tcp_clientconn,&server_ipaddr,server_port);//连接服务器
            if(err != ERR_OK)  netconn_delete(tcp_clientconn); //返回值不等于ERR_OK,删除tcp_clientconn连接
            else if (err == ERR_OK)    //处理新连接的数据
            { 
                struct netbuf *recvbuf;
                tcp_clientconn->recv_timeout = 10;
                netconn_getaddr(tcp_clientconn,&loca_ipaddr,&loca_port,1); //获取本地IP主机IP地址和端口号
                printf("连接上服务器%d.%d.%d.%d,本机端口号为:%d
    ",192,168, 1,105,loca_port);
                while(1)
                {
                    if(keyValue == KEY_LEFT)
                    {
                        tcp_client_flag = LWIP_SEND_DATA;
                        keyValue = 0;
                    }
                    if((tcp_client_flag & LWIP_SEND_DATA) == LWIP_SEND_DATA) //有数据要发送
                    {
                        err = netconn_write(tcp_clientconn ,tcp_client_sendbuf,strlen((char*)tcp_client_sendbuf),NETCONN_COPY); //发送tcp_server_sentbuf中的数据
                        if(err != ERR_OK)
                        {
                            printf("发送失败
    ");
                        }
                        tcp_client_flag &= ~LWIP_SEND_DATA;
                    }
                        
                    if((recv_err = netconn_recv(tcp_clientconn,&recvbuf)) == ERR_OK)  //接收到数据
                    {    
                        OS_ENTER_CRITICAL(); //关中断
                        memset(tcp_client_recvbuf,0,TCP_CLIENT_RX_BUFSIZE);  //数据接收缓冲区清零
                        for(q=recvbuf->p;q!=NULL;q=q->next)  //遍历完整个pbuf链表
                        {
                            //判断要拷贝到TCP_CLIENT_RX_BUFSIZE中的数据是否大于TCP_CLIENT_RX_BUFSIZE的剩余空间,如果大于
                            //的话就只拷贝TCP_CLIENT_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
                            if(q->len > (TCP_CLIENT_RX_BUFSIZE-data_len)) memcpy(tcp_client_recvbuf+data_len,q->payload,(TCP_CLIENT_RX_BUFSIZE-data_len));//拷贝数据
                            else memcpy(tcp_client_recvbuf+data_len,q->payload,q->len);
                            data_len += q->len;      
                            if(data_len > TCP_CLIENT_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出    
                        }
                        OS_EXIT_CRITICAL();  //开中断
                        data_len=0;  //复制完成后data_len要清零。                    
                        printf("%s
    ",tcp_client_recvbuf);
                        netbuf_delete(recvbuf);
                    }else if(recv_err == ERR_CLSD)  //关闭连接
                    {
                        netconn_close(tcp_clientconn);
                        netconn_delete(tcp_clientconn);
                        printf("服务器%d.%d.%d.%d断开连接
    ",192,168, 1,105);
                        break;
                    }
                }
            }
            OSTimeDly(10);
        }
    }

    里面核心的就是netconn的使用,这个熟能生巧

    忘了传代码,补上

    http://download.csdn.net/detail/dengrengong/8599071
  • 相关阅读:
    【转载】著名黑客雷蒙评价几种编程语言
    【GUI开发】Swing的一本极好的入门教材
    【数据结构】数组操作(HighArrayApp.java)
    数据另存为CSV档案(也是一种excel档案)【2】------自主选择路径
    TIniFile实现打开窗体后还原用户之前的配置的功能
    sql server内连接(inner join)、外连接(left outer join、right outer join、full outer join)、记录合并(union、union all)
    @指针、Cardinal()、Integer()、指针取值解析
    关于php编程的一些小技巧
    数据库操作,同时更新多条数据
    省份,城市,地区------三级联动菜单//要加注释
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4433729.html
Copyright © 2011-2022 走看看