具有非阻塞套接字的循环中的 read() 仅读取前 1024 个字节
read() in a loop with non-blocking socket only reads first 1024 bytes
socketRead()
中的以下代码正在发送 32K 字节的数据。但是,只读取前 1024 个字节。套接字是非阻塞的。我使用 EWOULDBLOCK
和 EAGAIN
不当吗?
我希望 socketRead()
中的代码继续循环读取整个 32K 字节,而不是在仅读取 1024 字节后停止。 我做错了什么?
int SetSocketNonBlocking(int socketfd)
{
return( fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NONBLOCK) );
}
int SocketReadReady(int sockfd, unsigned int timeoutSeconds)
{
fd_set set;
struct timeval timeout;
int retCode = 0;
FD_ZERO(&set);
FD_SET(sockfd, &set);
timeout.tv_sec = timeoutSeconds;
timeout.tv_usec = 0;
while(1)
{
retCode = select(sockfd+1, &set, NULL, NULL, &timeout);
if( (retCode == -1) && (errno == EINTR) )
{
continue;
}
else
{
break;
}
}
return( retCode == 1 );
}
uint8_t *SocketRead(int sockfd, int *bytesRead)
{
int size_recv = 0;
int total_size = 0;
uint8_t *data = NULL;
// initially we will provide ourselves with a 275k buffer
// which is more than large enough for a 3" x 8" rasterized image.
data = malloc((size_t)READ_CHUNK_SIZE * 275);
if( data != NULL )
{
if( SetSocketNonBlocking(sockfd) == -1 )
{
printf("Failed setting non-blocking\n");
}
if( SocketReadReady(sockfd, 10) )
{
printf("Socket ready for read\n");
do
{
// TODO: We need to at some point make sure to realloc() the buffer if we have to read more than
// 275k of data
size_recv = recv(sockfd, (void *)&data[total_size], READ_CHUNK_SIZE, MSG_DONTWAIT);
if( size_recv < 0 )
{
if( errno == EWOULDBLOCK )
{
break;
}
else if( errno == EAGAIN)
{
continue;
}
}
else if( size_recv == 0 )
{
// connection closed
printf("Connection closed\n");
break;
}
else
{
total_size += size_recv;
}
}while(1);
}
else
{
printf("Socket timed out waiting for data to read\n");
}
}
*bytesRead = total_size;
return data;
}
感谢大家的评论。以下代码现在可以正常工作。它可能需要一些改进,但它至少有效。
uint8_t *SocketRead(int sockfd, int *bytesRead)
{
int size_recv = 0;
int total_size = 0;
uint8_t *data = NULL;
// initially we will provide ourselves with a 275k buffer
// which is more than large enough for a 3" x 8" rasterized image.
data = malloc((size_t)READ_CHUNK_SIZE * 275);
if( data != NULL )
{
if( SetSocketNonBlocking(sockfd) == -1 )
{
printf("Failed setting non-blocking\n");
}
if( SocketReadReady(sockfd, 10,0) )
{
printf("Socket ready for read\n");
do
{
// TODO: We need to at some point make sure to realloc() the buffer if we have to read more than
// 275k of data
size_recv = read(sockfd, (void *)&data[total_size], READ_CHUNK_SIZE);
if( size_recv < 0 )
{
if( errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
{
if( SocketReadReady(sockfd,0,100) )
{
continue;
}
else
{
break;
}
}
else
{
perror("Socket read:");
if( data )
{
free(data);
data = NULL;
}
break;
}
}
else if( size_recv == 0 )
{
// connection closed
printf("Connection closed\n");
break;
}
else
{
total_size += size_recv;
}
}while(1);
}
else
{
printf("Socket timed out waiting for data to read\n");
}
}
*bytesRead = total_size;
return data;
}
socketRead()
中的以下代码正在发送 32K 字节的数据。但是,只读取前 1024 个字节。套接字是非阻塞的。我使用 EWOULDBLOCK
和 EAGAIN
不当吗?
我希望 socketRead()
中的代码继续循环读取整个 32K 字节,而不是在仅读取 1024 字节后停止。 我做错了什么?
int SetSocketNonBlocking(int socketfd)
{
return( fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NONBLOCK) );
}
int SocketReadReady(int sockfd, unsigned int timeoutSeconds)
{
fd_set set;
struct timeval timeout;
int retCode = 0;
FD_ZERO(&set);
FD_SET(sockfd, &set);
timeout.tv_sec = timeoutSeconds;
timeout.tv_usec = 0;
while(1)
{
retCode = select(sockfd+1, &set, NULL, NULL, &timeout);
if( (retCode == -1) && (errno == EINTR) )
{
continue;
}
else
{
break;
}
}
return( retCode == 1 );
}
uint8_t *SocketRead(int sockfd, int *bytesRead)
{
int size_recv = 0;
int total_size = 0;
uint8_t *data = NULL;
// initially we will provide ourselves with a 275k buffer
// which is more than large enough for a 3" x 8" rasterized image.
data = malloc((size_t)READ_CHUNK_SIZE * 275);
if( data != NULL )
{
if( SetSocketNonBlocking(sockfd) == -1 )
{
printf("Failed setting non-blocking\n");
}
if( SocketReadReady(sockfd, 10) )
{
printf("Socket ready for read\n");
do
{
// TODO: We need to at some point make sure to realloc() the buffer if we have to read more than
// 275k of data
size_recv = recv(sockfd, (void *)&data[total_size], READ_CHUNK_SIZE, MSG_DONTWAIT);
if( size_recv < 0 )
{
if( errno == EWOULDBLOCK )
{
break;
}
else if( errno == EAGAIN)
{
continue;
}
}
else if( size_recv == 0 )
{
// connection closed
printf("Connection closed\n");
break;
}
else
{
total_size += size_recv;
}
}while(1);
}
else
{
printf("Socket timed out waiting for data to read\n");
}
}
*bytesRead = total_size;
return data;
}
感谢大家的评论。以下代码现在可以正常工作。它可能需要一些改进,但它至少有效。
uint8_t *SocketRead(int sockfd, int *bytesRead)
{
int size_recv = 0;
int total_size = 0;
uint8_t *data = NULL;
// initially we will provide ourselves with a 275k buffer
// which is more than large enough for a 3" x 8" rasterized image.
data = malloc((size_t)READ_CHUNK_SIZE * 275);
if( data != NULL )
{
if( SetSocketNonBlocking(sockfd) == -1 )
{
printf("Failed setting non-blocking\n");
}
if( SocketReadReady(sockfd, 10,0) )
{
printf("Socket ready for read\n");
do
{
// TODO: We need to at some point make sure to realloc() the buffer if we have to read more than
// 275k of data
size_recv = read(sockfd, (void *)&data[total_size], READ_CHUNK_SIZE);
if( size_recv < 0 )
{
if( errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
{
if( SocketReadReady(sockfd,0,100) )
{
continue;
}
else
{
break;
}
}
else
{
perror("Socket read:");
if( data )
{
free(data);
data = NULL;
}
break;
}
}
else if( size_recv == 0 )
{
// connection closed
printf("Connection closed\n");
break;
}
else
{
total_size += size_recv;
}
}while(1);
}
else
{
printf("Socket timed out waiting for data to read\n");
}
}
*bytesRead = total_size;
return data;
}