tcp server socket 用select方式,检测select有读的事件,但读不出数据

weige250 2017-08-30 09:54:16
创建一tcp server socket,使用select多路io检测,很频繁的就检测到有client数据可读,但是读的时候都读不出来,代码有问题吗


{
int max_fd, tcom_fd, ret;
TCOM_MSG_HEADER msghdr;
fd_set write_set;
fd_set select_read_set;


short i =0;
struct sockaddr_in cli_addr;
int new_conn_fd = -1;

FD_ZERO(&write_set);
FD_ZERO(&select_read_set);

memset(&cli_addr, 0, sizeof(cli_addr));

tcom_fd = tcom_get_read_fd( MPU_MID_ASSIST );
if( tcom_fd < 0 )
{
log_e( LOG_ASSIST, "tcom_get_read_fd failed" );
return NULL;
}

ret = startCreateServerSocket();

if(ret !=0)
{
if(sock_fd >0)
{
close(sock_fd);
sock_fd = -1;
}
tm_start(recreate_timer,RECREATE_INTERVAL,TIMER_TIMEOUT_REL_ONCE);
}

while(1)
{
FD_ZERO(&select_read_set);
FD_SET(tcom_fd, &select_read_set);

if(sock_fd >0)
{
FD_SET(sock_fd, &select_read_set);
}

max_fd = tcom_fd > sock_fd ? tcom_fd : sock_fd;
for (i = 0; i < MAX_CLIENT_NUM; i++)
{
if(client_fd[i] <=0)
{
continue;
}

FD_SET(client_fd[i], &select_read_set);

if (max_fd < client_fd[i])
{
max_fd = client_fd[i];
}

log_i(LOG_ASSIST,"client_fd[%d]=%d",i,client_fd[i]);
}

//log_i(LOG_ASSIST,"max_fd=%d, sock_fd=%d, tcom_fd=%d",max_fd,sock_fd,tcom_fd);

/* monitor the incoming data */
ret = select( max_fd + 1, &select_read_set, NULL, NULL, NULL);
/* the file deccriptor is readable */
if( ret > 0)
{
if(FD_ISSET(tcom_fd, &select_read_set))
{
ret = tcom_recv_msg( MPU_MID_ASSIST, &msghdr, assist_msgbuf );
if( ret != 0 )
{
log_e( LOG_ASSIST, "tcom_recv_msg failed,ret:0x%08x", ret );
continue;
}
if(MPU_MID_ASSIST == msghdr.sender)
{
log_o( LOG_ASSIST,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>msghdr id is :%d\r\n",msghdr.msgid);
}
else if(MPU_MID_TIMER == msghdr.sender)
{
assit_timer_msg_proc(msghdr.msgid);
}
}

if (FD_ISSET(sock_fd, &select_read_set))
{
int len = sizeof(cli_addr);

new_conn_fd = accept(sock_fd, (struct sockaddr*)&cli_addr, &len);
log_i(LOG_ASSIST,"new client comes ,fd=%d\n",new_conn_fd);
if (new_conn_fd < 0)
{
log_e(LOG_ASSIST, "Fail to accept");
continue;
}
else
{
for (i = 0; i < MAX_CLIENT_NUM; i++)
{
if (client_fd[i] == -1)
{
client_fd[i] = new_conn_fd;
log_i(LOG_ASSIST,"add client_fd[%d]=%d",i,client_fd[i]);
FD_SET(new_conn_fd, &select_read_set);
if (max_fd < new_conn_fd)
{
max_fd = new_conn_fd;
}

unsigned short timerid = assist_assign_timer_to_fd(i);
assist_start_heartbeat_timer(timerid);
break;
}
}

if(i >=MAX_CLIENT_NUM)
{
close(new_conn_fd);
}
}
}

{
for (i = 0; i < MAX_CLIENT_NUM; i++)
{
int num =0;

if (-1 == client_fd[i]) {
continue;
}

memset(recv_buf, 0, BUFFER_SIZE);
if (FD_ISSET(client_fd[i], &select_read_set))
{
log_i(LOG_ASSIST,"start read Client(%d) :%d\n", i,client_fd[i]);
num = recv(client_fd[i], recv_buf, BUFFER_SIZE,MSG_DONTWAIT);
if (num > 0)
{
assist_restart_heartbeat_timer(assist_get_timerid(i));

log_buf_dump(LOG_ASSIST,"assist recv buff:",recv_buf,num);
}
else
{

}
}
}
}
}
else if ( 0 == ret ) /* timeout */
{
continue; /* continue to monitor the incomging data */
}
else
{
if( EINTR == errno ) /* interrupted by signal */
{
continue;
}

log_e( LOG_ASSIST, "assist_main exit, error:%s", strerror(errno));
break; /* thread exit abnormally */
}
}

return NULL;
}
...全文
406 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
jklinux 2017-08-30
  • 打赏
  • 举报
回复
for (i = 0; i < MAX_CLIENT_NUM; i++) { if (client_fd[i] == -1) { client_fd[i] = new_conn_fd; log_i(LOG_ASSIST,"add client_fd[%d]=%d",i,client_fd[i]); FD_SET(new_conn_fd, &select_read_set); if (max_fd < new_conn_fd) { max_fd = new_conn_fd; } //上面代码应是有新客户端连接时的,也就是sock_fd可读时的处理吧,这里用不着加入文件描述符的集合。 还有后面读文件描述符时,如对方已断线,没有看到有把那数组里存放的文件描述符改为-1
weige250 2017-08-30
  • 打赏
  • 举报
回复
多谢,看来是有新连接是添加监视描述符导致的

23,128

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧