windows的socket在创建后,默认是阻塞调用的,也就是说函数recv,recvfrom,send,sendto等函数都是阻塞的;那么我们如何将他们设置成非阻塞调用呢?我们可以通过windows为我们提供的ioctlsocket 函数实现;先给出一个例子:
BOOL LoadSocketSystem(void)
{
WORD wVersionRequested;
SOCKADDR_IN addrSrv;
BOOL bRet = FALSE;
WSADATA wsaData;
SOCKET sockClient;
int err;
int iMode;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return bRet;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return bRet;
}
s_socketStatus.m_hsocket = socket(AF_INET,SOCK_STREAM,0);
if( INVALID_SOCKET == s_socketStatus.m_hsocket )
{
WSACleanup( );
return bRet;
}
//-------------------------
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled;
// If iMode != 0, non-blocking mode is enabled.
iMode = 1;
ioctlsocket(s_socketStatus.m_hsocket,FIONBIO,(u_long FAR*) &iMode);
s_socketStatus.m_isConnected = TRUE;
sockClient = s_socketStatus.m_hsocket;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
return TRUE;
}
上面红色表示的就是将刚才创建的socket设置成非阻塞操作。
当然我们这样做是最简单的,但是如果对于一个复杂的系统,系统的其他部分可能已经对该socket调用了另两个windows函数--WSAAsyncSelect or WSAEventSelect ,这个个函数都是自动的将socket设置成非阻塞形式,所有在这样的情况下你调用ioctlsocket 想将其设置回阻塞形式是不会成功的;要想成功,你必须将由于调用上面两个函数对socket系统产生的影响clear掉,然后才能成功调用ioctlsocket 函数;如果clear呢?
如下调用WSAEventSelect函数:
rc = WSAEventSelect(s, hEventObject, 0);
如果想详细了解上述几个函数,请参阅MSDN。
分享到:
相关推荐
2. **非阻塞模式**:非阻塞模式下,Socket调用不会等待数据准备就绪,而是立即返回,无论数据是否可用。这样,程序可以继续执行其他任务,避免了阻塞导致的效率问题。然而,使用非阻塞模式需要编写更复杂的代码来...
#### 二、设置socket函数的非阻塞调用 在C++中,可以使用`ioctlsocket`函数来设置socket的工作模式(阻塞或非阻塞)。具体步骤如下: 1. **定义Socket** ```cpp SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0...
Linux下的Socket编程实例(阻塞和非阻塞) 通过分析给定的文件信息,我们可以生成以下知识点: Socket编程概述 Socket 编程是指使用操作系统提供的 socket 编程接口来实现网络通信的编程方式。Socket 编程可以实现...
非阻塞recvfrom的设置 在网络编程中,recvfrom函数是一个...使用ioctlsocket函数可以设置套接口的非阻塞模式,以便实现非阻塞的recvfrom函数。但是,我们需要注意ioctlsocket函数的使用和错误处理,以避免出现错误。
然后,通过调用`WSAAsyncSelect()`函数将Socket设置为非阻塞模式,或者使用`ioctlsocket()`函数配合`FIONBIO`标志。 超时设置通常涉及到两个方面:连接超时和读/写超时。对于连接超时,我们可以利用`setsockopt()`...
在Windows中,我们可以通过`ioctlsocket`函数和FIONBIO标志来设置socket为非阻塞模式。 以下是一个简化的多线程非阻塞模式的流程: 1. **初始化**: 在主线程中,启动服务器并创建监听socket。 2. **接收连接**: 当...
在Windows中,可以使用WSAAsyncSelect()或WSAEventSelect()函数将Socket设置为非阻塞模式,并与Windows消息机制相结合,实现异步事件通知。这两种方法允许程序在等待Socket事件的同时处理其他任务,提高了系统的并发...
而非阻塞模式下,Socket调用不会使调用线程挂起,而是立即返回,即使没有数据可读或可写。这样,程序可以同时处理多个事件,提高系统效率和响应性。 MFC通过CAsyncSocket类提供对非阻塞Socket的支持。CAsyncSocket...
Python的socket模块通过设置socket的选项,可以将socket转变为非阻塞模式。在非阻塞模式下,socket的send和recv等操作都会立即返回。如果操作不能立即完成,就会抛出异常或返回错误码。 多线程是实现非阻塞通讯的...
而非阻塞式调用则不会等待,即使数据未准备好,函数也会立即返回,让线程可以继续执行其他任务,如通过select或poll函数进行轮询检查数据是否就绪。 同步IO和异步IO的区别在于数据访问时进程是否被阻塞。同步IO在...
在非阻塞模式下,当调用read()或write()函数尝试从Socket读取或写入数据时,如果数据尚未准备好,这些函数不会阻塞,而是立即返回一个错误代码(通常为EAGAIN或EWOULDBLOCK)。这样,程序可以继续执行其他任务,或者...
`flags`参数可以设置一些选项,如非阻塞模式。 对于UDP类型的Socket,`sendto()`和`recvfrom()`函数用于指定发送或接收数据的目的地: ```c int sendto(SOCKET s, const char *buf, int len, int flags, const ...
4. 设置非阻塞模式:在Windows下,可以通过`ioctlsocket()`函数配合`FIONBIO`标志来设置`socket`为非阻塞模式。 5. 异步事件处理:`WSAAsyncSelect()`或`WSAEventSelect()`函数的使用,以及如何根据接收到的事件进行...
在QTcpSocket的编程中,我们经常会遇到阻塞和非阻塞两种模式的选择。这两种模式在处理网络通信时有着不同的行为和应用场景。 首先,阻塞模式意味着在执行某些操作(如连接、读取或写入数据)时,QTcpSocket会暂停...
对于非阻塞Socket,可以通过`fcntl()`函数设置文件描述符的标志位,添加`O_NONBLOCK`标志,使Socket处于非阻塞模式。在这种模式下,如果尝试读写数据时没有准备好,系统不会等待而是立即返回错误,从而避免了程序的...
调用者可以利用非阻塞调用来检查是否准备好执行某个操作,例如使用select函数。另外,即便对象处于阻塞模式,我们也可以通过某些API进行轮询状态,适时进行阻塞调用,从而避免阻塞。 C. 阻塞模式和阻塞函数调用 ...
CWSocket类可能通过设置socket的O_NONBLOCK标志实现了非阻塞模式。 多线程是现代应用程序处理并发任务的关键技术。在C++中,可以使用标准库中的std::thread或者在MFC中使用CWinThread来创建和管理线程。CWSocket类...
3. 建立 connect 连接,此时 socket 设置为非阻塞,connect 调用后,无论连接是否建立立即返回 -1,同时将 errno 设置为 EINPROGRESS。 4. 使用 select 函数等待正在后台连接的 connect 函数,可以设置一个 select ...
通过以上介绍,我们可以看到在Windows环境下设置socket连接超时的主要步骤包括:建立socket、设置非阻塞模式、调用connect、使用select检测socket状态、判断connect结果以及最后将socket恢复为阻塞模式。这些步骤...