anchises 发表于 2012-6-27 14:43:13

TCP发送数据

初次接触RT-Thread,想用stm32f107做一个串口服务器,程序用到了例程中所给的TCPCLIENT范例。
串口程序所采用的是中断和计时器超时的方式进行记录,即设置计时器超时,当串口数据在一段时间内,没有数据传入,说明数据已经全部传完,然后进行全部数据通过TCP传输。
此时,数据如何通过TCP传输?
我采用send或sendto函数,都会提示错误。
代码如下:
tcpclient函数,与PC连接正常,可发送数据。
void user_eth_tcpclient(const char* url, int port)
{
   char *recv_data;
   struct hostent *host;
   int sock, bytes_received;
   struct sockaddr_in server_addr;

   /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
   host = gethostbyname(url);
   /* 分配用于存放接收数据的缓冲 */
   recv_data = rt_malloc(1024);
   if (recv_data == RT_NULL)
   {
       rt_kprintf("No memory\n");
       return;
   }
   /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
   if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
   {
       /* 创建socket失败 */
       rt_kprintf("Socket error\n");
       /* 释放接收缓冲 */
       rt_free(recv_data);
       return;
   }
   /* 初始化预连接的服务端地址 */
   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons(port);
   server_addr.sin_addr = *((struct in_addr *)host->h_addr);
   rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
   /* 连接到服务端 */
   if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
   {
       /* 连接失败 */
       rt_kprintf("Connect error\n");
       /*释放接收缓冲 */
       rt_free(recv_data);
       return;
   }

   while(1)
   {
       /* 从sock连接中接收最大1024字节数据 */
       bytes_received = recv(sock, recv_data, 1024, 0);
       if (bytes_received <= 0)
       {
         /* 接收失败,关闭这个连接 */
         lwip_close(sock);

         /* 释放接收缓冲 */
         rt_free(recv_data);
         break;
       }
       /* 有接收到数据,把末端清零 */
       recv_data = '\0';

       if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
       {
         /* 如果是首字母是q或Q,关闭这个连接 */
         lwip_close(sock);

         /* 释放接收缓冲 */
         rt_free(recv_data);
         break;
       }
       else
       {
         /* 在控制终端显示收到的数据 */
         rt_kprintf("\nRecieved data = %s " , recv_data);                               
       }
       /* 发送数据到sock连接 */
       send(sock,tcpclient_send_data,strlen(tcpclient_send_data), 0);
   }
   return;
}
串口超时函数
void user_entry_usart1_timeout(void* parameter)
{       
        if(ussart1_timeout_bool!=usart1_rx_counter)
        {
//                rt_kprintf("usart1_timeout is timeout\n");
                USART_OUT(USART1,&usart1_rx_data,usart1_rx_counter);
//将数据通过TCP转发到PC

                usart1_rx_counter=0;
                rt_timer_stop(&usart1_timeout);
        }
        ussart1_timeout_bool++;       
}
将TCP转发到PC这一环节不值如何下手,采用send和sendto函数都会提示错误,求教。

anchises 发表于 2012-6-28 11:16:44

{:funk:}没有人能帮一下吗?

tiancaigao7 发表于 2012-6-29 10:39:12

从来没有遇到过send失败的情况,TCP我这边只要链接成功了,send一般没有问题。

anchises 发表于 2012-6-29 23:17:21

后来找到问题所在了,send函数不能放在中断函数中。
我想实现一个串口发送数据后,通过TCP转发的功能,bytes_received = recv(sock, recv_data, 1024, 0);函数会进行阻塞,无法调用send函数进行打断发送数据,后来采用bytes_received = recv(sock, recv_data, 1024, MSG_DONTWAIT);函数非阻塞,即可实用send函数,但是在函数中添加其他函数会出现hard fault on thread: init错误,请问如何解决。或者此类功能您是如何实现的。谢谢~

aozima 发表于 2012-6-29 23:42:30

RTOS处理问题的方式:
中断尽可能短。
中断通知应用程序去处理任务。

楼主需要了解的是 线程与线程 及 中断与线程 之间的 通信 和 同步 及 互斥。

anchises 发表于 2012-6-30 13:45:38

aozima 发表于 2012-6-29 23:42 static/image/common/back.gif
RTOS处理问题的方式:
中断尽可能短。
中断通知应用程序去处理任务。


好的,因为刚接触RTT,所以很多地方不是很了解,谢谢指点,我好好看一下说明。
页: [1]
查看完整版本: TCP发送数据