AcceptEx与WSARecv使用的问题

曾永红_ 2004-11-21 09:22:03
在我的程序中使用了AcceptEx与WSARecv函数

while (true)
{
if (AcceptEx (ListenSocket, AcceptSocket……) == FALSE)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
WinException exception (WSAGetLastError ());
continue;
}
……
if (WSARecv (AcceptSocket……) == SOCKET_ERROR )
{
WinException exception (WSAGetLastError ());
continue;
}

}
}
……
在调用WSARecv时总是会出错,提示为:"由于套接字没有联接,并且(当使用一个sendto调用发送数据报套接时)没有提供地址,发送或接收数据的请求没有被接受"

请问这是怎么回事啊,需要如何处理
...全文
445 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Guo Li 2005-01-14
  • 打赏
  • 举报
回复
在AcceptEx接收成功后,需要手动调用setsockopt函数来设置此socket为已联接状态,然后才能进行数据的收发工作
曾永红_ 2004-11-26
  • 打赏
  • 举报
回复
CSocket是我自己定的一个类
曾永红_ 2004-11-26
  • 打赏
  • 举报
回复
我把程序改了一下,没有直接在acceptex后接收发送数据了

if (GetQueuedCompletionStatus (hCompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData,(OVERLAPPED**)&lpOverlapped, INFINITE) == 0)
{
//throw (WinException (GetLastError ()));

WinException tmp (GetLastError ());
continue;
}

CSocket* pSocket = lpOverlapped ->sock;
//OVERLAPPED_BUF *pOverlappedBuf = m_OverlappedPool.GetOverlappedBuf ();


//TODO:TEST

if (pSocket ->Shutdown () == SOCKET_ERROR)
throw WinException (GetLastError ());

还是显示和上面一样的错误,咋回事啊,而且调用WSASend也会出同样的错误,但调用WSARecv不会有问题
joysun2000 2004-11-25
  • 打赏
  • 举报
回复
AcceptEx是非组塞的,而accept是阻塞的!
曾永红_ 2004-11-25
  • 打赏
  • 举报
回复
AcceptEx是为提高程序的性能
tangrh 2004-11-25
  • 打赏
  • 举报
回复
唉,看看windows网络编程第2版例子里,它有没有说acceptex干什么用啊,你得等它完成才能调用wsarecv啊,还是一个裸的套接字,你收什么呢?
sunhuiNO1 2004-11-25
  • 打赏
  • 举报
回复
accept也不一定是组塞的,看程序员的设置。
gdy119 2004-11-24
  • 打赏
  • 举报
回复
AcceptEx (ListenSocket, AcceptSocket……) == FALSE
错误,accept()
曾永红_ 2004-11-22
  • 打赏
  • 举报
回复
再顶一下
曾永红_ 2004-11-22
  • 打赏
  • 举报
回复
怎么没人回答?
曾永红_ 2004-11-21
  • 打赏
  • 举报
回复
快来帮帮忙啊
结构层次及相互联系 (1)、工作线程:响应连接的IO投递返回并负责投递读请求,并将IO返回结果投递给处理线程,可设定参数决定工作线程数量; (2)、处理线程:处理线程调用回调函数将信息传递给应用层或协议栈,可设定参数决定工作处理数量; (3)、看守线程:响应Accept事件调用AcceptEx,检测连接和心跳超时 ,将信息投递给工作线程,模块仅有一个看守线程。 1. 技术要求 (1)、线程同步:Lock指令、临界段; (2)、主要Socket API:WSASend、WSARecvAcceptEx、DisconnectEx; (3)、内存管理:连接池(句柄重用)、内存池; (4)、数据0拷贝:通过内置处理线程,上层应用可以避免自建线程池及复制数据的过程。同时提供GBuf内存分配功能,应用层获得分配地址及填充数据之后亦可直接投递给内核/驱动层; (5)、数据顺序同步:同一个连接同时只有一个处理线程响应其IO事件; (6)、IO请求投递:单投递读、多投递写; (7)、0缓冲读投递:可条件编译实现,以适用大规模连接要求。 (8)、超时机制:可设置空连接(连接不发送数据)超时时间以防止DOS攻击,也可设置心跳超时时间防止网络故障导致的现有连接成为虚连接避免耗尽系统资源。 (9)、接口技术:API、回调函数、客户句柄(客户连接句柄)。 (10)、主、被动发送:不使用HASH、MAP及LIST技术,即可提供安全可靠高效的客户连接句柄,以实现服务器端主被动发送数据功能; (11)、PerHandleData的回收不以IO投递的计数器或链表来做依据但仍能安全回收,同时尽量避免在高频的读写操作时做其他无关的操作以提高读写效率。 (12)、处理线程和工作线程有着良好分工界限,繁重的工作交给处理线程完成,工作线程工作量最大限度的减少,仅响应投递返回及读投递的操作; (13)、支持AWE,模块自动识别AWE是否开启(需手动开启),“否”则使用虚拟内存机制。 2. 功能要求 (1)、多IP多端口监听,每个监听可设置不同的回调函数,以高效的区别处理数据 (2)、可设置每秒最大的连接并发量和空连接(连接不发数据)超时时间以防止DOS攻击造成的服务瘫痪、具有心跳处理(防网络异常造成的虚连接)功能 (3)、不加协议的透明传输,可适用广泛的网络通讯环境 (4)、可现实主、被动发送数据,但不会因兼顾主动发送而额外增加降低效率的工作 (5)、内置处理线程,上层应用可不必自建线程池处理数据,所有IO事件按顺序调用回调函数并可以在回调函数内直接处理数据,不必担心多线程造成的接收数据乱序的问题。 (6)、高效率的数据对应关联机制,在初次连接并根据登录数据设置每个连接对应的宿主(Owner)之后,再接收的数据即可立即获得该连接对应的宿主,而不必再做额外的查询工作,并且模块内部采用的是指针关联方式,对于长连接、主动发送的服务器系统而言是高效率的。 (7)、可兼容IPv6 3. 注意事项 因硬件环境和应用环境不同,不合理的配置会出现效率及性能上的问题,因此以下情况出现时,请务必与作者联系以确保获得更好的参数配置: (1)、连接量超过1000个的。超过的应结合具体硬件配置和网络带宽等因素综合设定运行参数。 (2)、带宽使用率超过20%的。工作线程和处理线程数量的设置也是综合考虑数据吞吐量和数据处理负载的因素来设置的,过多的线程会在调度上浪费时间,同时也应该综合考虑线程优先级别来设置工作线程和处理线程数量,两者的设置也不一定能相等。 (3)、服务器端有主动发送需求的、短连接(含网络故障造成的连接断开)出现频率高的。 压力测试工具介绍: 一、 使用G-TcpClient模块 二、 可以设定间隔时间发起大规模长、短连接 三、 可以发起密集数据包,包括即时和定时发送,1M的光纤带宽最大可以达到100K/S(单向)以上,100M本地网最大可以达到10M/S(单向)以上 四、 数据发送仅由一个独立线程但当,每点击一次Connect就创建一个线程根据当前参数发起连接。 五、 测试前提:服务器接收客户端数据后立即原样返回给客户端
IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序。与使用select()或是其它异步方法不同的是,一个套接字[socket]与一个完成端口关联了起来,然后就可继续进行正常的Winsock操作了。然而,当一个事件发生的时候,此完成端口就将被操作系统加入一个队列中。然后应用程序可以对核心层进行查询以得到此完成端口。 大体上来讲,使用完成端口只用遵循如下几个步骤: (1) 调用 CreateIoCompletionPort() 函数创建一个完成端口,而且在一般情况下,我们需要且只需要建立这一个完成端口,把它的句柄保存好,我们今后会经常用到它…… (2) 根据系统中有多少个处理器,就建立多少个工作者(为了醒目起见,下面直接说Worker)线程,这几个线程是专门用来和客户端进行通信的,目前暂时没什么工作; (3) 下面就是接收连入的Socket连接了,这里有两种实现方式:一是和别的编程模型一样,还需要启动一个独立的线程,专门用来accept客户端的连接请求;二是用性能更高更好的异步AcceptEx()请求。 (4) 每当有客户端连入的时候,我们就还是得调用CreateIoCompletionPort()函数,这里却不是新建立完成端口了,而是把新连入的Socket(也就是前面所谓的设备句柄),与目前的完成端口绑定在一起。 至此,我们其实就已经完成了完成端口的相关部署工作了,嗯,是的,完事了,后面的代码里我们就可以充分享受完成端口带给我们的巨大优势,坐享其成了,是不是很简单呢? (5) 例如,客户端连入之后,我们可以在这个Socket上提交一个网络请求,例如WSARecv(),然后系统就会帮咱们乖乖的去执行接收数据的操作,我们大可以放心的去干别的事情了; (6) 而此时,我们预先准备的那几个Worker线程就不能闲着了, 我们在前面建立的几个Worker就要忙活起来了,都需要分别调用GetQueuedCompletionStatus() 函数在扫描完成端口的队列里是否有网络通信的请求存在(例如读取数据,发送数据等),一旦有的话,就将这个请求从完成端口的队列中取回来,继续执行本线程中后面的处理代码,处理完毕之后,我们再继续投递下一个网络通信的请求就OK了,如此循环。

18,355

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧