【发布时间】:2013-03-19 15:44:35
【问题描述】:
我有一个在 WinXp(i7, 2.1 Ghz) 上运行的主从应用程序 Master,而从属应用程序是一个控制器板。主站向从站发送请求,从站作为响应循环向主站发送数据。从机循环发送的数据为每 0.5 毫秒 1000 字节。 当master发出发送数据的请求时,控制台报错。
“Select() 函数错误代码:: 10038”。
这是WSAENOTSOCK的代码。
此应用程序是一个单线程应用程序,从从站接收数据。 从错误来看,套接字似乎在 select 函数检查之前已关闭。
谁能给我指个方向?
:::源代码::::
int Receive()
{
int rc;
socklen_t cli_alen;
struct timeval to;
fd_set read_fd, write_fd, excep_fd;
FD_ZERO(&write_fd);
FD_ZERO(&excep_fd);
sock_again:
if (!_isSocketOpen)
{
return 0;
}
FD_ZERO(&read_fd);
FD_SET(_sock_fd, &read_fd);
to.tv_sec = 0;
to.tv_usec = 0;
cli_alen = sizeof(SOCKADDR_IN);
rc = select(_sock_fd+1, &read_fd, &write_fd, &excep_fd, &to);
if (rc == 0 )
{ // Timeout
// printf("XCP Port %d : select() timded out \n", _port);
acess = 1;
goto sock_again;
}
else if (rc == SOCKET_ERROR)
{
// Error
LogError("XCP: select() error %d", WSAGetLastError());
closesocket(_sock_fd);
return -1;
}
else
{
// Data
if (!FD_ISSET(_sock_fd, &read_fd))
{
LogError("XCP: select() wrong socket descr");
return -1;
}
else
{
//read data
rc = recvfrom(_sock_fd, (char *)_recvBuf, UDP_RECVBUFLEN, 0, (LPSOCKADDR)&_saddr, &cli_alen);
}
}
}
:::: 已编辑 ::::
int CloseUdpConnection()
{
if (closesocket(_sock_fd) == SOCKET_ERROR) {
LogError("closesocket() error: %d", WSAGetLastError());
return -1;
}
_isSocketOpen = 0;
LogError("successfully closed socket %s:%d", _address, _port);
return 0;
}
::::: 调试跟踪 :::::
xcpApplication.exe -i 192.168.1.100 -p 5555
c
--> Connecting...
<-- Connection established
t
--> Setting daq signal list...
Sorting daq signal list...
Sorting done
<-- Daq signal list set
d
--> Configuring daq lists...
<-- Configuration done
r
--> Starting measurement...
<-- Measurement started
**_sock_fd: -448997078**
XCP: select() error 10038
::::: 跟踪 ::::
--> Starting measurement...
<-- Measurement started
_sock_fd: -1963260928
_sock_fd: 0x8afb0400
XCP: select() error 10038
:::::: 跟踪 ::::
xcpApplication.exe -i 192.168.1.100 -p 5555
_sock_fd: 1936 _sock_fd: 0x790
successfully opened socket 192.168.1.100:5555
--> Connecting...
<-- Connection established
t
--> Setting daq signal list...
Sorting daq signal list...
Sorting done
<-- Daq signal list set
d
--> Configuring daq lists...
<-- Configuration done
c
--> Connecting...
<-- Connection established
r
--> Starting measurement...
<-- Measurement started
_sock_fd: 901186560 _sock_fd: 0x35b70400
XCP: select() error 10038
【问题讨论】:
-
由于您没有使用
write_fd或except_fd,您可以将NULL传递给select()。 -
另外,您将超时设置为
0,这意味着您只是在检查是否有任何数据可用。您可以通过在套接字上设置非阻塞模式并调用recvfrom来获得相同的行为。 -
数据接收和传递的频率需要足够快,所以我使用立即超时,否则由于缓冲区溢出导致数据包丢失。
-
这不是超时的作用。
-
来源-MSDN Select函数:如果TIMEVAL初始化为{0, 0},select会立即返回;这用于轮询所选套接字的状态。如果 select 立即返回,则 select 调用被认为是非阻塞的,并且适用非阻塞调用的标准假设。