socket编程一般都是阻塞模式,例如accept函数,connect函数,send函数,recv函数。这些函数都是阻塞模式,对于单片机来说,阻塞模式处理起来需要浪费一个任务,如果这几个函数是阻塞模式,那么需要再其他任务做超时和异常处理。显然会浪费任务数量,对于本来就不多的单片机内存资源就是雪上加霜。那么必须设置位非阻塞态。让函数立即返回。如果出错直接执行出错路径。
方法1. 使用select函数和recv函数进行配合。
例如接收函数代码如下:
int eth_read(int fd,char *buf,int len,int time_out)
{
fd_set rfd;
struct timeval tv;
int nfd = 0;
tv.tv_usec = 00;
tv.tv_sec = 1;
FD_ZERO(&rfd);
FD_SET(fd,&rfd);
nfd = select(fd + 1,&rfd, NULL, NULL, &tv);
if(nfd < 0)
{
return -1;
}
else if(nfd == 0)
{
return 0;
}
else
{
nfd = read(fd,buf,len);
}
return nfd;
}
int eth_write(int fd,char *buf,int len,int time_out)
{
fd_set wfd;
struct timeval tv;
int nfd = 0;
tv.tv_usec = 00;
tv.tv_sec = 1;
FD_ZERO(&wfd);
FD_SET(fd,&wfd);
nfd = select(fd + 1, NULL, &wfd, NULL, &tv);
if(nfd < 0)
{
return -1;
}
else if(nfd == 0)
{
return 0;
}
else
{
nfd = write(fd,buf,len);
}
nfd = lwip_send(fd,buf,len,MSG_DONTWAIT);
return nfd;
}
方法2.使用 ioctlsocket函数设置非阻塞模式
代码如下:
int creat_socket(int protocl)
{
int block = 1;
int comm_tick = 0;
int sockfd= socket(AF_INET6, SOCK_STREAM, 0);
if(sockfd , 0)
{
return -1;
}
ioctlsocket(sockfd,FIONBIO,&block);
return sockfd;
}
后续的accept函数 send ,recv,connect 函数都是非阻塞模式。方便应用层处理。