《windows网络编程》第一版的程序里关于Select模型的例子里有这个函数
而第二版里nonblocking的例子,也就是select模型,没有此函数我的程序里,定义了2个UDP socket绑定在同一IP,2个端口上。
如果不用这个ioctlsocket设置socket的话,那么select不能正常运行,程序总是停在select这里。
但是只要用ioctlsocket设置一个socket的话,就可以正常运行了。那么ioctlsocket这个函数在Select模型中是必须的吗?非常感谢!!
而第二版里nonblocking的例子,也就是select模型,没有此函数我的程序里,定义了2个UDP socket绑定在同一IP,2个端口上。
如果不用这个ioctlsocket设置socket的话,那么select不能正常运行,程序总是停在select这里。
但是只要用ioctlsocket设置一个socket的话,就可以正常运行了。那么ioctlsocket这个函数在Select模型中是必须的吗?非常感谢!!
#include "winsock2.h"#define LOCALIP "192.168.3.96"
#define LOCALPORT 8201
#define LOCALPORT1 8101#define REMOTEIP "192.168.3.96"
#define REMOTEPORT 8787
#define BUFSIZE 1024int main(int argc, char* argv[])
{
SOCKET s, s1;
int Ret;
WSADATA wsaData;
SOCKADDR_IN localAddr, remoteAddr, localAddr1;
int localAddrLen, remoteAddrLen, localAddrLen1;
fd_set fdRead;
fd_set fdWright;
fd_set fdExcept;
int retSelect;
char buf[BUFSIZE]; if ((Ret = WSAStartup(0x0202,&wsaData)) != 0)
{
printf("WSAStartup() failed with error %d\n", Ret);
WSACleanup();
return 1;
}
// if ((s = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_IP, NULL, 0,
// WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == INVALID_SOCKET)
{
printf("create socket error\n");
return 1;
}
localAddr.sin_addr.s_addr = inet_addr(LOCALIP);
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(LOCALPORT);
localAddrLen = sizeof(SOCKADDR_IN);
if (bind(s, (SOCKADDR *)&localAddr, localAddrLen) == SOCKET_ERROR)
{
printf("bind error\n");
return 1;
} if ((s1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == INVALID_SOCKET)
{
printf("create socket error\n");
return 1;
}
localAddr1.sin_addr.s_addr = inet_addr(LOCALIP);
localAddr1.sin_family = AF_INET;
localAddr1.sin_port = htons(LOCALPORT1);
localAddrLen1 = sizeof(SOCKADDR_IN);
if (bind(s1, (SOCKADDR *)&localAddr1, localAddrLen1) == SOCKET_ERROR)
{
printf("bind error\n");
return 1;
} ULONG nonBlock = 1;
// if (ioctlsocket(s, FIONBIO, &nonBlock) == SOCKET_ERROR)
// {
// printf("ioctlsocket error\n");
// return 1;
// }
// if (ioctlsocket(s1, FIONBIO, &nonBlock) == SOCKET_ERROR)
// {
// printf("ioctlsocket error\n");
// return 1;
// } while (1)
{
FD_ZERO(&fdRead);
FD_ZERO(&fdWright);
FD_ZERO(&fdExcept);
FD_SET(s, &fdRead);
FD_SET(s1, &fdRead); printf("selecting¡­¡­\n");
if (retSelect = select(s + 1, &fdRead, &fdWright, &fdExcept, NULL))
{
if (retSelect == SOCKET_ERROR)
{
printf("select error\n");
return 1;
} if (FD_ISSET(s, &fdRead))
{
remoteAddrLen = sizeof(SOCKADDR_IN);
int nret;
if ((nret = recvfrom(s, buf, BUFSIZE, 0, (SOCKADDR *)&remoteAddr,
&remoteAddrLen)) == SOCKET_ERROR)
{
printf("recvfrom error\n");
break;
}
else
{
buf[nret] = '\0';
printf("[%s] send msg: %s\n",
inet_ntoa(remoteAddr.sin_addr), buf);
}
}
if (FD_ISSET(s1, &fdRead))
{
remoteAddrLen = sizeof(SOCKADDR_IN);
int nret;
if ((nret = recvfrom(s1, buf, BUFSIZE, 0, (SOCKADDR *)&remoteAddr,
&remoteAddrLen)) == SOCKET_ERROR)
{
printf("recvfrom1 error\n");
break;
}
else
{
buf[nret] = '\0';
printf("[%s] send msg1: %s\n",
inet_ntoa(remoteAddr.sin_addr), buf);
}
}
if (FD_ISSET(s, &fdWright))
{
printf("fdWright\n");
}
if (FD_ISSET(s, &fdExcept))
{
printf("fdExcept\n");
}
}
}
return 0;
}
如果不使用ioctlsocket sock 默认为阻塞模式
在使用SELECT的时候要改成 非阻塞模式