完成端口中ConnectEx的问题:
完成端口用于客户端时一定要注意,创建的SOCKET要先随便绑定一个端口(默认0自动分配也可),然后再扔到完成端口中去,之后才可以ConnectEx,否则(不绑定),ConnectEx会出现10022错误。同时,getpeername似乎对ConnectEx不支持,也可能有其他细节设置我暂时不知道,返回的远程地址是无效的(仅对于完成端口用于服务器accept回来的SOCKET有效,对用于客户的connet也有效)。不过对程序没有太大影响,既然是自己要主动连出去,远程地址当然自己早就心里明白了,自己保存一份即可,不必getpeername。备注:getsockname返回本地地址一直是有效的。
getpeername之所以取不到正确的内容,是因为ConnectEx返回后,socket相关的属性还没有更新(ConnectEx的特性所导致),你应该调用一下setsockopt更新socket的属性后再调用getpeername。参数是SOL_SOCKET和SO_UPDATE_CONNECT_CONTEXT。
When the ConnectEx function returns, the socket s is in the default state for a connected socket. The socket s does not enable previously set properties or options until SO_UPDATE_CONNECT_CONTEXT is set on the socket. Use the setsockopt function to set the SO_UPDATE_CONNECT_CONTEXT option.
For example:
err = setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
完成端口与ACE框架:
平台不同,使用的ACE框架还是有所差别的。比如