野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 24246|回复: 1

【LWIP】使用socket write丢数据的问题

[复制链接]

发表于 2020-7-17 11:01:49 | 显示全部楼层 |阅读模式
20火花
自己移植了ucosiii 加 lwip 2.1.2,这几天测试,代码做客户端发送数据给上位机,上位机接收的数据很多都是断句,一句正常一句断的那种,测试还字发送了200字节,不知道有什么问题,希望各路大神帮忙瞧上一眼。

先上soket发送这部分代码

  1. #include "tcp_server_demo.h"
  2. #include "lwip/opt.h"
  3. #include "lwip_comm.h"
  4. #include "led.h"
  5. #include "lwip/lwip_sys.h"
  6. #include "lwip/api.h"
  7. #include <lwip/sockets.h>

  8. u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE];        //TCP客户端接收数据缓冲区
  9. u8 tcp_server_sendbuf[]="0123456789abcdefghijklmnopqrstuvwxyz,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,YZ9876543210\r\n\
  10. 0123456789abcdefghijklmnopqrstuvwxyz,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,YZ9876543210 \r\n";

  11. u8 tcp_server_flag;                                                                //TCP服务器数据发送标志位
  12. const char tcp_server_addr[] = "192.168.1.124";

  13. //tcp服务器任务
  14. void tcp_server_thread(void *arg)
  15. {
  16.         OS_ERR err;
  17.         int sock_fd = -1;
  18.         u32 num = 0;
  19.         int error = -1,len_t = 0;
  20.         struct sockaddr_in client_addr;
  21.        
  22.         OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);
  23.         while(1)
  24.         {
  25.                 //创建tcp套接字
  26.                 sock_fd = socket(AF_INET, SOCK_STREAM, 0);
  27.                 if(sock_fd < 0)
  28.                 {
  29.                         printf("Failed to request Socket memory!\r\n");
  30.                         OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);
  31.                         continue;
  32.                 }
  33.                
  34.                 //设置socket 为 Non-blocking模式
  35.                 int flags = fcntl(sock_fd, F_GETFL, 0);
  36.                 fcntl(sock_fd, F_SETFL, flags|O_NONBLOCK);
  37.                
  38.                 client_addr.sin_family = AF_INET;
  39.                 client_addr.sin_port = htons(TCP_SERVER_PORT);
  40.                 client_addr.sin_addr.s_addr = inet_addr(tcp_server_addr);
  41.                 memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));
  42.                
  43.                 // connect 连接服务器,在Non-blocking模式下立即返回
  44.                 if(connect(sock_fd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) < 0)
  45.                 {
  46.                         if(errno != EINPROGRESS)
  47.                         {
  48.                                 printf("connect failed! len = %d, num = %d\r\n",sizeof(tcp_server_sendbuf), num);
  49.                                 closesocket(sock_fd);
  50.                                 OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//1s 重连一次
  51.                                 continue;
  52.                         }
  53.                         else
  54.                         {
  55.                                 fd_set rfds, wfds;  
  56.                                 struct timeval tv;  

  57.                                 FD_ZERO(&rfds);  
  58.                                 FD_ZERO(&wfds);  
  59.                                 FD_SET(sock_fd, &rfds);  
  60.                                 FD_SET(sock_fd, &wfds);  
  61.                                 /* set select() time out */  
  62.                                 tv.tv_sec = 10;   
  63.                                 tv.tv_usec = 0;
  64.                                
  65.                                 if(select(sock_fd + 1, &rfds, &wfds, NULL, &tv) > 0)
  66.                                 {
  67.                                         if(FD_ISSET(sock_fd, &rfds) && FD_ISSET(sock_fd, &wfds))  
  68.                                         {
  69.                                                 socklen_t len = sizeof(error);
  70.                                                 if(getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) < 0)
  71.                                                 {
  72.                                                         printf("getsockopt error!!!\r\n");
  73.                                                         printf("3connect failed! len = %d, num = %d\r\n",sizeof(tcp_server_sendbuf), num);
  74.                                                         closesocket(sock_fd);
  75.                                                         OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//1s 重连一次
  76.                                                         continue;
  77.                                                 }
  78.                                                 else
  79.                                                 {
  80.                                                         if(error == 0)
  81.                                                         {
  82.                                                                 //printf(" OOOOOOOOOOOKKKKKKKKKKKKKKKKK\r\n");
  83.                                                         }
  84.                                                         else
  85.                                                         {
  86.                                                                 printf("connect getsockopt error!!!\n");
  87.                                                                 printf("3connect failed! len = %d, num = %d\r\n",sizeof(tcp_server_sendbuf), num);
  88.                                                                 closesocket(sock_fd);
  89.                                                                 OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//1s 重连一次
  90.                                                                 continue;
  91.                                                         }
  92.                                                 }
  93.                                         }
  94.                                         else if(!FD_ISSET(sock_fd, &rfds) && FD_ISSET(sock_fd, &wfds))
  95.                                         {
  96.                                                 //printf(" 2OOOOOOOOOOOKKKKKKKKKKKKKKKKK\r\n");
  97.                                         }
  98.                                 }
  99.                                 else
  100.                                 {
  101.                                         printf("3connect failed! len = %d, num = %d\r\n",sizeof(tcp_server_sendbuf), num);
  102.                                         closesocket(sock_fd);
  103.                                         OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//1s 重连一次
  104.                                         continue;
  105.                                 }
  106.                         }
  107.                 }
  108.                
  109.                 //fcntl(sock_fd, F_SETFL, flags&~O_NONBLOCK);
  110.                 printf("Connect to server: %s successful!\r\n", tcp_server_addr);
  111.                 while(1)
  112.                 {
  113.                         //接收数据
  114.                         len_t = read(sock_fd, tcp_server_recvbuf, TCP_SERVER_RX_BUFSIZE);
  115.                         if(len_t < 0)
  116.                         {
  117.                                 //printf("socket read error!\r\n");
  118.                         }
  119.                         else
  120.                         {
  121.                                 printf("socket read len = %d ,buf = %s\r\n", len_t, tcp_server_recvbuf);
  122.                         }
  123.                        
  124.                         num++;
  125.                         //发送数据
  126.                         if(write(sock_fd, tcp_server_sendbuf, sizeof(tcp_server_sendbuf)) < 0)
  127.                         {
  128.                                 if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
  129.                                 {
  130.                                         //printf();
  131.                                 }
  132.                                 else
  133.                                 {
  134.                                         printf("socket send data error!\r\n");
  135.                                         break;
  136.                                 }
  137.                         }
  138.                 }
  139.                
  140.                 closesocket(sock_fd);
  141.         }
  142. }
复制代码


然后配置了几个发送有关的参数,如下截图
1.png
2.png

最后是上位机接收的数据,很多都丢失了,
2020-07-17 10-39-47屏幕截图.png
2020-07-17 10-40-18屏幕截图.png
2020-07-17 10-39-58屏幕截图.png

以下是我的工程,希望有大神指点一下,谢谢谢谢
ucosiii移植lwip2.1.2.zip (5.51 MB, 下载次数: 4)

回复

使用道具 举报

 楼主| 发表于 2020-7-17 15:35:08 | 显示全部楼层
同一个工程,使用netconn 写的服务器端,发送就没有这个问题,可能跟我设置的非阻塞模式有点关系,搞不懂

  1. void tcp_server_thread(void *arg)
  2. {
  3.         CPU_SR_ALLOC();
  4.        
  5.         u32 data_len = 0;
  6.         struct pbuf *q;
  7.         err_t err,recv_err;
  8.         u8 remot_addr[4];
  9.         struct netconn *conn, *newconn;
  10.         static ip_addr_t ipaddr;
  11.         static u16_t                         port;
  12.         u32 num = 0;
  13.         LWIP_UNUSED_ARG(arg);

  14.         conn = netconn_new(NETCONN_TCP);  //创建一个TCP链接
  15.         netconn_bind(conn,IP_ADDR_ANY,TCP_SERVER_PORT);  //绑定端口 8号端口
  16.         netconn_listen(conn);                  //进入监听模式
  17.         conn->recv_timeout = 10;          //禁止阻塞线程 等待10ms
  18.         while (1)
  19.         {
  20.                 err = netconn_accept(conn,&newconn);  //接收连接请求
  21.                 if(err==ERR_OK)newconn->recv_timeout = 10;

  22.                 if (err == ERR_OK)    //处理新连接的数据
  23.                 {
  24.                         struct netbuf *recvbuf;

  25.                         netconn_getaddr(newconn,&ipaddr,&port,0); //获取远端IP地址和端口号
  26.                        
  27.                         remot_addr[3] = (uint8_t)(ipaddr.addr >> 24);
  28.                         remot_addr[2] = (uint8_t)(ipaddr.addr>> 16);
  29.                         remot_addr[1] = (uint8_t)(ipaddr.addr >> 8);
  30.                         remot_addr[0] = (uint8_t)(ipaddr.addr);
  31.                         printf("主机%d.%d.%d.%d连接上服务器,主机端口号为:%d , len = %d\r\n",remot_addr[0], remot_addr[1],remot_addr[2],remot_addr[3],port, sizeof(tcp_server_sendbuf));
  32.                        
  33.                         while(1)
  34.                         {
  35.                                 num++;
  36.                                 err = netconn_write(newconn ,tcp_server_sendbuf,strlen((char*)tcp_server_sendbuf),NETCONN_COPY); //发送tcp_server_sendbuf中的数据
  37.                                 if(err != ERR_OK)
  38.                                 {
  39.                                         printf("发送失败\r\n");
  40.                                         netconn_close(newconn);
  41.                                         netconn_delete(newconn);
  42.                                         printf("主机:%d.%d.%d.%d断开与服务器的连接 num = %d\r\n",remot_addr[0], remot_addr[1],remot_addr[2],remot_addr[3], num);
  43.                                         break;
  44.                                 }
  45.                         }
  46.                 }
  47.         }
  48. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-21 19:07 , Processed in 0.030935 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表