如何才能“雅致”关闭“I/O完成端口模型”里的client-socket ???

huangbeyond 2002-12-08 10:32:43
我使用“I/O完成端口模型”做一个服务器程序。当客户机连接上来时,自然是由“监听SOCKET”生出对应的“Client-socket”。现在,问题是:如果才能“雅致”地关闭这些SOCKET。直接使用closesocket()来关闭,是必然导致客户端出现"10053"(连接被强制关闭)号错误的。

我也知道用shutdown(),但是,对“I/O完成端口模型”中的client-socket执行shutdown()之后,“工作者线程”所管理的完成端口,根本收不到任何信息。难道是shutdown()不能用于被“完成端口”所关联的SOCKET吗?那么,在“完成端口”模型的服务器里,我该如何去“雅致”关闭一个连接呢????
...全文
105 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
huangbeyond 2002-12-17
  • 打赏
  • 举报
回复
再推推.....
realdreamer 2002-12-17
  • 打赏
  • 举报
回复
不是很清楚你的意思, 写了个测试程序, 你先看看, 运行一下.


// sdk.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "shell32.lib")
#pragma comment (lib, "comctl32.lib")


DWORD WINAPI ThreadProc(PVOID pData)
{
cout << "客户等待 3 秒... " << endl;
Sleep(3000);
SOCKET client = socket(AF_INET, SOCK_STREAM, 0);


sockaddr_in addr;
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(80);

int ret = connect(client, (sockaddr*)&addr, sizeof(addr));
if (ret != SOCKET_ERROR)
{
cout << "客户连接成功" << endl;
}
else
{
cout << "客户连接失败" << endl;
exit(0);
}

HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (SOCKET_ERROR==WSAEventSelect(client, hEvent, FD_CLOSE))
{
cout << "WSAEventSelect call failed" << endl;
}


WaitForSingleObject(hEvent, INFINITE);

WSANETWORKEVENTS netevents;
WSAEnumNetworkEvents(client, hEvent, &netevents);
if (netevents.lNetworkEvents & FD_CLOSE)
{
cout << "客户接收到 CLOSE 消息" << endl;

cout << "ErrorCode : " << netevents.iErrorCode[FD_CLOSE_BIT] << endl;
exit(0);
}

return 0;
}


void main()
{
WSADATA data;
WSAStartup(0x202, &data);

HANDLE hThread;

//启动客户线程
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
HANDLE hIOCP;
hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (hIOCP == NULL)
{
cout << "CreateIoCompletionPort call failed!" << endl;
return;
}
SOCKET server;
server= WSASocket(AF_INET, SOCK_STREAM, 0, NULL, NULL, WSA_FLAG_OVERLAPPED);
if (server == INVALID_SOCKET)
{
cout << "WSASocket call failed!" << endl;
return;
}
sockaddr_in addr;
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
bind(server, (sockaddr*)&addr, sizeof(sockaddr_in));
listen(server, 2);


cout << "服务器已准备接受客户连接 ... " << endl;
SOCKET sockAccept = accept(server, NULL, NULL);
if (sockAccept != INVALID_SOCKET)
{
cout << "服务器接受连接" << endl;
}

if ( !CreateIoCompletionPort((HANDLE)sockAccept, hIOCP, 0, 1))
{
cout << "CreateIoCompletionPort call failed" << endl;
exit(0);
}

cout << "服务器等待 3 秒... " << endl;

Sleep(3000);
// 服务器开始 shutdown ...
cout << "服务器开始 shutdown ... " << endl;
Sleep(500);
shutdown(sockAccept, SD_SEND);
Sleep(20000);

cout << "服务器套接字关闭" << endl;
closesocket(sockAccept);
WSACleanup();
}

cbc 2002-12-15
  • 打赏
  • 举报
回复
gz
huangbeyond 2002-12-15
  • 打赏
  • 举报
回复
没有人来解答我的问题了么。。。。。。。。。。。。。
luixui 2002-12-15
  • 打赏
  • 举报
回复
gz
up
up
up
huangbeyond 2002-12-15
  • 打赏
  • 举报
回复
gzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!!
huangbeyond 2002-12-13
  • 打赏
  • 举报
回复
我就是参照那个代码修改的啊.
而且,<Windows网络编程>的"IOCP"代码里,也没有"雅致关闭SOCKET"的部分啊!!
sinsky 2002-12-12
  • 打赏
  • 举报
回复
不会的,是不是你写的代码有问题?
参考一下Network Programming for Microsoft Windows, Second Edition
里的IOCP是怎么写的,再试试
huangbeyond 2002-12-11
  • 打赏
  • 举报
回复
to:sinsky(十方)

我的意思是:
我现在在服务端程序里,对一个已经连接的client-socket调用 shutdown()无效也就是说,IO完成端口的代码里,响应不到该消息.
我该如何处理?
sinsky 2002-12-11
  • 打赏
  • 举报
回复
其实跟服务器用什么模型是无关的
如果像你说的那样,检查一下你的客户端的设计吧
puyinghua 2002-12-10
  • 打赏
  • 举报
回复
1、要么由客户端先ShutDown(SD_BOTH)或取别的参数, 当然是看需要吧
肯定先shutdown调用先, 再closesocket的
2、或者由客户或是服务端,当服务完成时发送一个自定义消息, 当此事件发生时回调函数OnYOurEven 再shutdown closesocket

以上只是设想, 呵呵, 能不能"雅致"关闭, 试试吧, :)
huangbeyond 2002-12-10
  • 打赏
  • 举报
回复
首先确定一个前提:我是用"IO完成端口"模型的.其它的WINSOCK IO模型没有这个问题.


TO:yanhuahui(眼发黑)

在服务器程序中,对一个已经连接的SOCKET,只用closesocket()是会造成对方SOCKET产生一个10053错误的,我实验了无数次了,呵呵.而且,使用closesocket()来一次就强制关闭,是非常不安全的,这也是MS文档资料里非常不提倡的.

那么,如何才能“雅致”关闭“I/O完成端口模型”里的client-socket 呢??
realdreamer 2002-12-10
  • 打赏
  • 举报
回复
同楼上
yanhuahui 2002-12-10
  • 打赏
  • 举报
回复
不会吧,我就是用closesocket();没有你那种情况。
huangbeyond 2002-12-09
  • 打赏
  • 举报
回复
没有哪位朋友对这个技术比较熟悉吗?

有的话,还请多多帮助.
zhenxizhou 2002-12-08
  • 打赏
  • 举报
回复
gz
huangbeyond 2002-12-08
  • 打赏
  • 举报
回复
希望有经验的朋友给我帮助!!!

18,356

社区成员

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

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