|
各位好!最近要用到以太网通信,系统是rt-thread,根据官方的TCP客户端例程,
修改了几个地方,加入了TCP断开之后的重新连接,测试了一天没有出现问题,欢迎讨论 ,
- #include <rtthread.h>
- //#include <lwip/netdb.h> /* 为了解析主机名,需要包含netdb.h头文件 */
- //#include <lwip/sockets.h> /* 使用BSD socket,需要包含sockets.h头文件 */
- #include <sys/socket.h> /* 使用BSD socket,需要包含sockets.h头文件 */
- #include "netdb.h"
- /* 服务器地址或者域名 */
- char tcp_url[32] = "192.168.1.17";
- /* 端口号 */
- int tcp_c_port = 12345;
- static const char send_data[] = "This is TCP Client from rt-thread "; /* 发送用到的数据 */
- #define BUFSZ 512
- void tcpclient(void *p)
- {
- int ret;
- char *recv_data;
- struct hostent *host;
- int sock, bytes_received;
- struct sockaddr_in server_addr;
-
- /*地址和端口号 */
- char* url = tcp_url;
- int port = tcp_c_port;
- /* 需要等待PHY芯片初始化完成 */
- rt_thread_delay(100);
-
- /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
- host = gethostbyname(url);
- /* 分配用于存放接收数据的缓冲 */
- recv_data = rt_malloc(BUFSZ);
- 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));
- /* 连接到服务端 最多尝试连接 5次 */
- if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
- {
-
- }
- while(1)
- {
- /* 从sock连接中接收最大BUFSZ - 1字节数据 */
- bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
- if (bytes_received < 0)
- {
- /* TCP重连 */
- goto again;
- }
- else if (bytes_received == 0)
- {
- /* 这种情况就是链路断开了?? */
- /* 打印recv函数返回值为0的警告信息 */
- rt_kprintf("\nReceived warning,recv function return 0.\r\n");
-
- /* TCP重连 */
- goto again;
-
- }
- /* 有接收到数据,把末端清零 */
- recv_data[bytes_received] = '\0';
- rt_kprintf("\nReceived data\n = %s " , recv_data);
-
- /* 发送数据到sock连接 */
- ret = send(sock,send_data_buffer, 138, 0);
- if (ret > 0)
- {
- /* 数据发送成功 直接退出即可 */
- }
- else if (ret < 0)
- {
- /* 发送失败,重新连接 */
- rt_kprintf("\n send error,close the socket.\r\n");
-
- /* 重连*/
- goto again;
- }
- else if (ret == 0)
- {
- /* 打印send函数返回值为0的警告信息 */
- rt_kprintf("\n Send warning,send function return 0.\r\n");
-
- /* 重连*/
- goto again;
- }
-
- /* 客户端和服务器连接正常情况下执行到此处即可 */
- continue;
- /* 客户端重连部分 */
- again:
- {
- /* 链接失败 关闭SOCKET */
- closesocket(sock);
-
- rt_thread_delay(1);
-
- /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- /* 创建socket失败 */
- rt_kprintf("Socket error\n");
- return;
- }
-
- if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
- {
- /* 连接失败 */
- rt_kprintf("Connect fail!\n");
- /* 稍微延时一下 */
-
- rt_thread_delay(100);
-
- /* TCP重连 */
- goto again;
- }
- }
- #if 0
- erro:
- {
- /* 连接失败 */
- rt_kprintf("Connect fail!\n");
- closesocket(sock);
- /*释放接收缓冲 */
- rt_free(recv_data);
- return;
- }
- #endif
- }
- }
- /* 线程栈大小 */
- #define THREAD_STACK_SIZE 512
- /* 优先级 */
- #define THREAD_PRIORITY 22
- /* 线程时间片 */
- #define THREAD_TIMESLICE 10
- int tcp_client_thread_init(void)
- {
- rt_thread_t tid;
- tid = rt_thread_create("tcp_c",
- tcpclient, RT_NULL,
- THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
- if (tid != RT_NULL)
- rt_thread_startup(tid);
-
- return 0;
- }
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- /* 输出tcpclient函数到finsh shell中 */
- FINSH_FUNCTION_EXPORT(tcp_client_thread_init, startup tcp client);
- #endif
复制代码 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|