我正在尝试使用select()
解决套接字超时问题的读取问题。不幸的是,此函数在被调用后立即返回-1
。什么可能是错的?
commStatus communicate( const char * tx, char * rx, const int bufSize , const char * inetAddr, const int port )
{
commStatus r;
if (!sockInitialised) initSock();
if (sockInitialised)
{
SOCKET s;
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr(inetAddr);
server.sin_family = AF_INET;
server.sin_port = htons( port );
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
std:stringstream d; d <<"Could not create socket : " << WSAGetLastError();
LogIt(d,Level::Error);
} else
{
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
r= commStatus::COMM_NO_TRANSMIT ;
} else
{
int l =strlen(tx)+strlen("DATA ");
char* dtx ;
dtx = (char*) calloc(sizeof(char),strlen(tx)+strlen("DATA ") + 1 );
sprintf(dtx,"DATA %s",tx);
if( send(s , dtx , strlen(dtx) , 0) < 0)
{
puts("Send failed");
r= commStatus::COMM_NO_TRANSMIT;
} else
{
int recv_size = 0;
struct timeval selTimeout;
selTimeout.tv_sec = 20; /* timeout (secs.) */
selTimeout.tv_usec = 0; /* 0 microseconds */
fd_set readSet;
FD_ZERO(&readSet);
#define STDIN_FILENO 0
FD_SET(STDIN_FILENO, &readSet);//stdin manually trigger reading
FD_SET(s, &readSet);//tcp socket
int numReady = select(s+1, &readSet, NULL, NULL, &selTimeout);
if(numReady > 0)
{
if((recv_size = recv(s , rx , bufSize ,0)) == SOCKET_ERROR)
{
r= commStatus::COMM_NO_RECEIVE;
} else
{
rx[recv_size] = '\0';
r= commStatus::COMM_OK;
}
} else r=commStatus::COMM_NO_RECEIVE;
}
free(dtx);
}
}
} else r= commStatus::COMM_NO_TRANSMIT;
return r;
}
答案 0 :(得分:0)
在C下,您可以检查errno
变量,它应该告诉您导致错误的特定问题。
或者,您可能拥有perror()
函数,该函数将为您提供可读的版本:
#include <stdio.h>
:
perror ("select");
如果你在 Windows下, WSAGetLastError()
将作为errno
变量,this page提供可能性和解释:
WSANOTINITIALISED - 在使用此功能之前,必须成功进行WSAStartup调用。
WSAEFAULT - Windows套接字实现无法为其内部操作分配所需的资源,或者readfds,writefds,exceptfds或timeval参数不属于用户地址空间。
WSAENETDOWN - 网络子系统发生故障。
WSAEINVAL - 超时值无效,或者所有三个描述符参数均为空。
WSAEINTR - 通过WSACancelBlockingCall取消阻止Windows Socket 1.1调用。
WSAEINPROGRESS - 正在阻止Windows Sockets 1.1调用,或者服务提供商仍在处理回调函数。
WSAENOTSOCK - 其中一个描述符集包含一个不是套接字的条目。
答案 1 :(得分:0)
据我所知,您正试图将stdin
传递给Winsock的select()
函数。
不幸的是,在Windows下,select()
只接受套接字句柄,而不是通用文件描述符。
如果你打电话给WSAGetLastError()
,你可能会看到它返回WSAENOTSOCK
。