请问如何在线程中响应和处理 Winsock 的 FD_ACCEPT 等消息? (100分)

  • 主题发起人 主题发起人 truest9
  • 开始时间 开始时间
T

truest9

Unregistered / Unconfirmed
GUEST, unregistred user!
一般情况下,我用 WSAAsyncSelect(ListenSocket,FWindow,WM_SOCKET_UMC,FD_ACCEPT or FD_CLOSE or FD_READ); 将一个 Socket 的消息投递到程序的主窗口,然后在进程(主线程)中处理这个消息。

我打算将这个操作放到一个新线程中处理。
却发现,WSAAsyncSelect是通过窗口句柄来投递的,线程也有这个句柄吗?
或是通过别的方法实现。请教各位了
 
TSocketThread = class(TThread)
private
FWindow: THandle;
protected
procedure WindowMethod(var Message: TMessage);
public
constructor Create
destructor Destroy; override;
end;

// create thread
constructor TSocketThread.Create;
begin
inherited Create(True);
FWindow := AllocateHWnd(WindowMethod); // 安装消息截获函数
// execute thread
Resume;
end;

// destroy thread
destructor TSocketThread.Destroy;
begin
DeallocateHWnd(FWindow); // 释放消息截获句柄
...
inherited Destroy;
end;

// 响应Windows消息
procedure TSocketThread.WindowMethod(var Message: TMessage);
begin
with Message do
case Msg of
FD_ACCEPT: ....;
FD_CLOSE:...;
FD_READ:....;
else
Result := DefWindowProc(FWindow, Msg, wParam, lParam);
end;
end;
end;

用TSocketThread 的FWindows设置消息投递即可:
WSAAsyncSelect(ListenSocket,FWindow,WM_SOCKET_UMC,FD_ACCEPT or FD_CLOSE or FD_READ);
 
DefWindowProc在哪里定义的?
设置消息投递时,还是投递到主线程的窗体上吗。
我的程序有多个这样的处理线程,我怎么样才能让每一个线程为一个客户机服务?
 
》DefWindowProc在哪里定义的?
Windows:
function DefWindowProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;

》设置消息投递时,还是投递到主线程的窗体上吗。
不是,可以投递到任何地方,在哪指定WindowMethod就投到哪。

》我的程序有多个这样的处理线程,我怎么样才能让每一个线程为一个客户机服务?
主线程处理未联接的Socket的消息;联接建立后,创建线程,把Socket句柄ListenSocket传给线程,线程内将Socket绑定指定的WindowMethod上。
 
我对这段代码还不太理解
我照搬上去,还是没有反应,请apw帮我解释一下。
我的程序是这样工作的
启动程序时,创建一个监听线程,当发现一个用户连接时,就为这个用户创建一个控制线程
监听线程继续监以接受新的用户连接。创建好的控制线程可用和这个用户单独“对话”。
原理很简单。我现在刚刚扔掉控件,走进 WinSock 的大门,有很多问题。请apw多帮忙。
 
》当发现一个用户连接时,就为这个用户创建一个控制线程
》监听线程继续监以接受新的用户连接。创建好的控制线程可用和这个用户单独“对话”。
我不太明白,如果用线程的话我见议你最好还是用同步方式来写吧。
异步情况下你每创建一个线程就要定义不同的消息创建不同的虚拟窗体句柄来对应。
 
leaber,你说的正好是我的疑问
》异步情况下你每创建一个线程就要定义不同的消息创建不同的虚拟窗体句柄来对应。
这个虚拟窗体如何创建???
WSAAsyncSelect需要把消息送到一个窗体过程

当然,你说到的用同步方式来做,非常愿意听你仔细说说。
 
看样子老大没有使用过 Timer 控件。
 
哈哈,小雨哥也来了
点拨一下吧。我现在是卡在这里了。
 
呵呵,看一下CLIENTSOCKET的源码里面的异步实现讲的很清楚!
function TCustomWinSocket.GetHandle: HWnd;
begin
if FHandle = 0 then
FHandle := AllocateHwnd(WndProc);
//这里实现了虚拟窗口,为以后的消息响应做准备
Result := FHandle;
end;
大不了你就多ALLOCATEHWND()几次吧!异步就是为单线来实现的,考虑一下同步方式吧!!
 
to 小雨哥,leaber
总算有点明白了, AllocateHwnd实际上创建了一个不可见的窗体,此窗体的窗体过程由 AllocateHwnd参数指定。
原来Timer控件是用AllocateHwnd创建了一个窗体,在这个窗体中响应 WM_TIMER 消息。
结贴。
 
以后有问题,你们要鼎立帮忙啊
 
后退
顶部