我的部分线程创建部分代码如下:
rt_thread_t ss1_thread = rt_thread_create("ss1", sensor_task, (void*)1, 2048, 10, 200);
rt_thread_startup(ss1_thread);
rt_thread_t ss2_thread = rt_thread_create("ss2", sensor_task, (void*)2, 2048, 10, 200);
rt_thread_startup(ss2_thread);
rt_thread_t ss3_thread = rt_thread_create("ss3", sensor_task, (void*)3, 2048, 10, 200);
rt_thread_startup(ss3_thread);
rt_thread_t ss4_thread = rt_thread_create("ss4", sensor_task, (void*)4, 2048, 10, 200);
rt_thread_startup(ss4_thread);
现成方法sensor_task代码如下:
static void sensor_task(void *param){
m_msleep(2000);
do{
if(socket_init((int)param) == RET_OK){
parse_sensor_data((int)param);
}else{
m_msleep(3000);
}
}while(1);
}
socket_init代码如下:
ret_t socket_init(int id){
// LOG_I("socket init:%d", id);
rt_mutex_take(lock[id], RT_WAITING_FOREVER);
if(sock[id] >= 0){
closesocket(sock[id]);
sock[id] = -1;
}
int new_sock = socket(AF_INET, SOCK_STREAM, 0);
if (new_sock == -1)
{
LOG_E("Socket[%d] error\n", id);
// rt_kprintf("Socket[%d] create error\n", id);
rt_mutex_release(lock[id]);
return RET_FAIL;
}
struct timeval tv_out = {60, 0};
if(id >= 1 && id <= 4){
tv_out.tv_sec = 60;
}else{
tv_out.tv_sec = 10;
}
// if(id == IDX_LIGHT){
// tv_out.tv_sec = 3;
// }
setsockopt(new_sock, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out));
tv_out.tv_sec = 3;
setsockopt(new_sock, SOL_SOCKET, SO_CONTIMEO, &tv_out, sizeof(tv_out));
int val = 1;
setsockopt(new_sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
// 设置 KeepAlive 时间(单位:秒)
int keepidle = 5; // 5秒后开始发送探测包
setsockopt(new_sock, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle));
// 设置 KeepAlive 探测间隔
int keepintvl = 1; // 每 1秒 发送一次探测包
setsockopt(new_sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl));
// 设置 KeepAlive 探测次数
int keepcnt = 1; // 最多 1 次探测包
setsockopt(new_sock, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt));
// 直接解析IP地址
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port[id]);
// 关键:使用inet_pton替代getaddrinfo
if (inet_pton(AF_INET, url[id], &server_addr.sin_addr) <= 0) {
rt_kprintf("Invalid IP address: %s\n", url[id]);
closesocket(new_sock);
rt_mutex_release(lock[id]);
return RET_FAIL;
}
// 连接服务器
if (connect(new_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == 0) {
sock[id] = new_sock;
rt_mutex_release(lock[id]);
return RET_OK;
} else {
closesocket(new_sock);
rt_mutex_release(lock[id]);
return RET_FAIL;
}
}
parse_sensor_data方法的话,就是调用recv,判断接收到的字节,如果≤0,就return RET_IO(丢失链接);接收到数据的话,就按照对应的数据发送一些信号量,或者修改一些自己的变量,没有动底层的东西。
|